我有一個程序任務來執行表的一致性更新。爲了簡單起見,我將討論虛擬表格來展示這個想法。所以我有兩個表格:user
和note
。MySQL - 通過兩個併發進程一致選擇和更新
的note
有id
(主鍵自動增加)和user_id
(外鍵),number
和next_number
。
number
是一些用戶的說明。如果這是最新的用戶註釋或者可以等於下一個用戶註釋的數量(如C++鏈接列表中下一個節點的指針),則next_number
可以等於0
。
因此,每個用戶的音符編號從1到n。
現在有的兩個過程(過程Proc1 和 PROC2 )有需要將行插入到表note
爲相同的用戶。
所以每個該處理開始交易,獲取最新的用戶注意到的number
,然後執行一些其他動作與number
遞增到1
插入新行是否有可能,這兩個進程(過程Proc1和PROC2)將取回他們的交易中相同number
(說第一個進程將執行SELECT
語句之前第二個進程將執行其INSERT
和UPDATE
語句)?
例如:
- 過程Proc1:
SELECT number FROM note WHERE user_id = 1 AND next_number = 0
- 檢索數 - PROC2:
SELECT number FROM note WHERE user_id = 1 AND next_number = 0
- 檢索數 - 過程Proc1:
INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc1 note'
- PROC2:
INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc2 note'
- 過程Proc1 :
UPDATE note SET next_number = 6 WHERE number = 5
- PROC2:
UPDATE note SET next_number = 6 WHERE number = 5
- 過程Proc1:commiting的過程Proc1交易
- PROC2:commiting PROC2
如果有可能的交易,如何避免這種情況? SELECT ... FOR UPDATE
會解決這個問題嗎?
更新 - 簡化我的問題
所以一般的問題是,如果進程啓動的事務如何禁止其他MySQL會話與當前交易正與該行的互動?
這是一個好主意,使'筆記'列也自動增量。然後使用update未設置next_number =(select last_insert_id())where next_number = 0;當然,需要在交易中完成整個事情。 –
自動增量確保生成值的唯一性,但不是正確的順序。沒有任何保證它會產生一個「1,2,3」序列而不是「1,3,4」。同樣在我的情況下,'note'表格包含不同用戶的註釋。所以自動增量在這裏不是一種方法。 –