MySQL死鎖簡單案例演示

2021-08-31 09:46:19 字數 4015 閱讀 5663

請各位讀者對本篇文章採取疑問的態度。

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...