請各位讀者對本篇文章採取疑問的態度。
1.環境
2.示例1
mysql>
create
table t (i int
)engine
=innodb
;query ok,
0rows affected (
0.26 sec)
mysql>
start
transaction
;query ok,
0rows affected (
0.03 sec)
mysql>
select
*from t where i =
1lock
inshare
mode;+
------+
| i |
+------+|1
|+------+
1row
inset
(0.00 sec)
mysql>
start
transaction
;query ok,
0rows affected (
0.00 sec)
mysql>
delete
from t;
error 1205
(hy000): lock wait timeout exceeded; try restarting transaction
上面的這個超時錯將會在命令執行一段時間之後,才出現。其超時時間預設設定為50s:
mysql>
show variables like
'innodb_lock_wait_timeout';+
--------------------------+-------+
| variable_name |
value|+
--------------------------+-------+
| innodb_lock_wait_timeout |50|
+--------------------------+-------+
1row
inset
,1 warning (
0.03 sec)
在這個出錯命令尚未出現之前,在client a中繼續執行如下命令:
mysql>
delete
from t where i =1;
query ok,
1row affected (
0.00 sec)
結果在client b中出現的結果如下:
mysql>
delete
from t where i =1;
error 1213
(40001
): deadlock found when trying to get lock
; try restarting transaction
3.示例2【外來鍵約束至死鎖】create
table
`parent`
(`id`
int(11)
notnull
,primary
key(
`id`))
engine
=innodb
default
charset
=utf8
create
table
`child`
(`id`
int(11)
default
null
,key
`id_for`
(`id`),
constraint
`id_for`
foreign
key(
`id`
)references
`parent`
(`id`))
engine
=innodb
default
charset
=utf8
mysql>
begin
;query ok,
0rows affected (
0.03 sec)
mysql>
delete
from parent where id =3;
query ok,
1row affected (
0.01 sec)
在session b執行如下命令:
mysql>
begin
;query ok,
0rows affected (
0.00 sec)
mysql>
insert
into child select
3;
發現session b的回話一直呈阻塞態。
檢視information_schema.innodb_locks
表資料,如下:
mysql>
select
*from information_schema.innodb_locks\g**
****
****
****
****
****
****
*1.row***
****
****
****
****
****
****
lock_id: 21305:145:3:4
lock_trx_id: 21305
lock_mode: s
lock_type: record
lock_table: `insidemysql`
.`parent`
lock_index: primary
lock_space: 145
lock_page: 3
lock_rec: 4
lock_data: 3**
****
****
****
****
****
****
*2.row***
****
****
****
****
****
****
lock_id: 21303:145:3:4
lock_trx_id: 21303
lock_mode: x
lock_type: record
lock_table: `insidemysql`
.`parent`
lock_index: primary
lock_space: 145
lock_page: 3
lock_rec: 4
lock_data: 3
2rows
inset
,1 warning (
0.01 sec)
發現出現死鎖。
死鎖過程很簡單:session a首先發起乙個事務(以begin起),接著欲刪除parent表中id=3的行記錄。這個操作會發起鎖操作,申請乙個x鎖【如上述sql所示,lock_trx_id為21303,其lock_mode為x型】。然後另外的乙個回話session b發起乙個事務(begin起),欲插入一條id=3的記錄【如上述sql所示,lock_trx_id為21305,其lock_mode為s型】。但是因為parent表中的id是child表中的id的外來鍵,所以導致阻塞的產生。注意它們的lock_id 以及lock_data均相同,表明鎖住的行記錄相同。
4. 參考文章
2.《mysql技術內幕:innodb儲存引擎》
簡單多執行緒死鎖案例
在多執行緒程式中死鎖的乙個令人頭疼的問題,為了避免死鎖就要避免死鎖產生,就要知道死鎖產生的條件 死鎖產生的原因是同步巢狀,所以在開發過程中要盡量避免同步巢狀 下面是我的乙個簡單的同步死鎖案例 定義兩個鎖 class lock寫乙個執行緒 public class threaddemo4 extend...
mysql 死鎖案例及分析過程
一致性的非鎖定讀是指innodb儲存引擎通過行多版本控制 mvcc自行了解 的方式來讀取當前執行時間資料庫中行的資料,而不需要等待訪問的行上x鎖的釋放。在innodb儲存引擎的預設設定下,這是預設的讀取方式 ps 1.該技術不會有額外的開銷,因為讀取的快照資料其實是行資料之前的版本資料,該實現是通過...
MySQL幻讀解釋及案例演示
幻讀 t1讀取了乙個字段,t2對欄位進行了插入。此時t1再次讀取時仍然為原來的資料,不過t1如果對t2插入行同樣進行插入時就會報錯。例項 實驗環境 mysql 5.6.43,事務自動提交進行關閉 set autocommit 0 實驗流程 建立連個session,乙個進行事務一t1,乙個執行事務二t...