mysql中死鎖
推薦課程:MySQL教程。
死鎖的關(guān)鍵在于:兩個(gè)(或以上)的Session加鎖的順序不一致。
那么對(duì)應(yīng)的解決死鎖問(wèn)題的關(guān)鍵就是:讓不同的session加鎖有次序
案例
需求:將投資的錢拆成幾份隨機(jī)分配給借款人。
起初業(yè)務(wù)程序思路是這樣的:
投資人投資后,將金額隨機(jī)分為幾份,然后隨機(jī)從借款人表里面選幾個(gè),然后通過(guò)一條條select for update 去更新借款人表里面的余額等。
例如兩個(gè)用戶同時(shí)投資,A用戶金額隨機(jī)分為2份,分給借款人1,2
B用戶金額隨機(jī)分為2份,分給借款人2,1
由于加鎖的順序不一樣,死鎖當(dāng)然很快就出現(xiàn)了。?
對(duì)于這個(gè)問(wèn)題的改進(jìn)很簡(jiǎn)單,直接把所有分配到的借款人直接一次鎖住就行了。
Select * from xxx where id in (xx,xx,xx) for update
在in里面的列表值mysql是會(huì)自動(dòng)從小到大排序,加鎖也是一條條從小到大加的鎖
例如(以下會(huì)話id為主鍵): Session1: mysql> select * from t3 where id in (8,9) for update; +----+--------+------+---------------------+ | id | course | name | ctime | +----+--------+------+---------------------+ | 8 | WA | f | 2016-03-02 11:36:30 | | 9 | JX | f | 2016-03-01 11:36:30 | +----+--------+------+---------------------+ rows in set (0.04 sec) Session2: select * from t3 where id in (10,8,5) for update; 鎖等待中…… 其實(shí)這個(gè)時(shí)候id=10這條記錄沒有被鎖住的,但id=5的記錄已經(jīng)被鎖住了,鎖的等待在id=8的這里 不信請(qǐng)看 Session3: mysql> select * from t3 where id=5 for update; 鎖等待中 Session4: mysql> select * from t3 where id=10 for update; +----+--------+------+---------------------+ | id | course | name | ctime | +----+--------+------+---------------------+ | 10 | JB | g | 2016-03-10 11:45:05 | +----+--------+------+---------------------+ row in set (0.00 sec) 在其它session中id=5是加不了鎖的,但是id=10是可以加上鎖的。