由于某些原因,沒有使用并發,而是通過mysql資料庫的表來代替佇列。
具體陳述句是
先執行sql = 'SELECT * FROM resource_trading_center_yeji where is_deleted is null and project_source = "'+center_name+'" for update'
后執行sql = 'update resource_trading_center_yeji set is_deleted=1 where url=%s;'
中間沒有commit
鎖的等待超時設定為了1秒
場景是:一堆實體遍歷plugins,plugs有各自的center_name,遍歷程序中可能重復
project_source和is_deleted都有索引,按理說只會添加行鎖,即便執行'update resource_trading_center_yeji set is_deleted=1 where url=%s;'時添加了表鎖(url沒有索引),但多個session并沒有交叉等待鎖。
不清楚為什么死鎖,照理說應該等鎖超時才對。
謝謝解答
uj5u.com熱心網友回復:
我想到一個場景:時間A:
會話A在執行,還沒執行完,那么就是表鎖;
同時,會話B也發起了SQL,由于會話A是表鎖,那么對于會話B的for update陳述句被堵塞,第二條SQL等待執行;
同時,會話C也發起了SQL,由于會話A是表鎖,那么對于會話C的for update陳述句被堵塞,第二條SQL等待執行;
假設會話B和會話C的center_name不同;
時間B:
會話A執行完,釋放所有鎖;
同一時間:
會話B獲取了center_name1對應的行鎖;
會話C獲取了center_name2對應的行鎖;
當會話B想要執行update,需要獲取表鎖,但是被會話C的行鎖阻塞,等待會話C釋放行鎖;
當會話C想要執行update,需要獲取表鎖,但是被會話B的行鎖阻塞,等待會話B釋放行鎖;
相互等待,超過1秒,死鎖回滾。
uj5u.com熱心網友回復:
謝謝。是有這種可能性,但我只開了2個會話測驗,實在不清楚怎么會死鎖
uj5u.com熱心網友回復:
兩個會話測驗,那就是兩個會話同時獲得了行鎖,各自的表鎖都相互阻塞吧
uj5u.com熱心網友回復:
log里顯示其中一個session居然請求了primary index鎖,求解,如何解決以下是日志:
------------------------
LATEST DETECTED DEADLOCK
------------------------
2019-07-17 13:47:07 0x404
*** (1) TRANSACTION:
TRANSACTION 1139555, ACTIVE 0 sec fetching rows
mysql tables in use 3, locked 3
LOCK WAIT 357 lock struct(s), heap size 41168, 3 row lock(s)
MySQL thread id 79, OS thread handle 15284, query id 118858 localhost ::1 root Sending data
SELECT * FROM resource_trading_center_yeji where is_deleted is null and project_source = "馬賽克" for update
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 227 page no 988 n bits 1192 index index4 of table `zhixing`.`resource_trading_center_yeji` trx id 1139555 lock_mode X locks rec but not gap waiting
Record lock, heap no 144 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
0: SQL NULL;
1: len 8; hex 800000000001d52d; asc -;;
*** (2) TRANSACTION:
TRANSACTION 1139552, ACTIVE 13 sec fetching rows, thread declared inside InnoDB 3032
mysql tables in use 1, locked 1
2923 lock struct(s), heap size 286928, 3003 row lock(s), undo log entries 53
MySQL thread id 80, OS thread handle 1028, query id 118859 localhost ::1 root updating
update resource_trading_center_yeji set is_deleted=1 where url='http://ggzy.yn.gov.cn/jyxx/jsgcZbjggsDetail?guid=b87b9fcb-1f33-46db-b003-542792366d4b&isOther=false'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 227 page no 988 n bits 1192 index index4 of table `zhixing`.`resource_trading_center_yeji` trx id 1139552 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: SQL NULL;
1: len 8; hex 800000000001d73c; asc <;;
Record lock, heap no 670 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: SQL NULL;
1: len 8; hex 800000000001d73b; asc ;;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 227 page no 2630 n bits 136 index PRIMARY of table `zhixing`.`resource_trading_center_yeji` trx id 1139552 lock_mode X locks rec but not gap waiting
Record lock, heap no 63 PHYSICAL RECORD: n_fields 7; compact format; info bits 0
0: len 8; hex 8000000000012d08; asc - ;;
1: len 6; hex 00000010b676; asc v;;
2: len 7; hex f4000001cc0110; asc ;;
3: len 30; hex e4ba91e58d97e79c81e585ace585b1e8b584e6ba90e4baa4e69893e4b8ad; asc ; (total 33 bytes);
4: len 30; hex e7baa2e6b2b3e5b79ee4b8aae697a7e5b88232303139e5b9b4e59f8ee995; asc 2019 ; (total 116 bytes);
5: len 30; hex 687474703a2f2f67677a792e796e2e676f762e636e2f6a7978782f6a7367; asc http://ggzy.yn.gov.cn/jyxx/jsg; (total 99 bytes);
6: len 1; hex 81; asc ;;
*** WE ROLL BACK TRANSACTION (1)
uj5u.com熱心網友回復:
for update 會加上獨占鎖 然后事務一直不提交的話,第二個UPDATE也想加獨占鎖 需要等第一個事務釋放,然后一直等不到釋放就事務超時了轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/55805.html
標籤:MySQL
上一篇:使用sum很慢的問題
