發(fā)生的原因
-
例子
例子
mysql 加上行鎖
行鎖導致的死鎖
什么是死鎖
死鎖是指兩個或者兩個以上的事務在執(zhí)行過程中常侦,因爭奪資源而造成的一種互相等待的現(xiàn)象紊册。
死鎖產(chǎn)生的必要條件
-
互斥
- 并發(fā)執(zhí)行的事務為了進行必要的隔離保證執(zhí)行正確辆亏,在事務結束前衡蚂,需要對修改的數(shù)據(jù)庫記錄持鎖评雌,保證多個事務對相同數(shù)據(jù)庫記錄串行修改氯质。
- 對于大型并發(fā)系統(tǒng)無法避免。
-
請求與保持
- 已經(jīng)持有一個資源鎖档址,等待另外一個資源鎖
- 死鎖僅發(fā)生在請求兩個或者兩個以上的鎖對象的時候
- 由于應用的需要盹兢,難以消除
-
不剝奪
- 已經(jīng)獲得鎖資源的事務,在未執(zhí)行前守伸,不能被強行剝奪绎秒,只能在使用完成后,由事務自己釋放含友。
- 一般用于已經(jīng)出現(xiàn)死鎖時替裆,通過破壞該條件達到解除死鎖的目的校辩。
- 數(shù)據(jù)庫系統(tǒng)通常通過一定的死鎖檢測機制發(fā)現(xiàn)死鎖窘问,強制回滾代價相對較小的事務,達到解除死鎖的目的宜咒。
-
環(huán)路等待
環(huán)路等待- 發(fā)生死鎖時惠赫,必然存在一個事務 —— 鎖的環(huán)形鏈。
- 按照同一順序獲取鎖故黑,可以破壞該條件儿咱。
- 通過分析死鎖事物之間的鎖競爭關系庭砍,調(diào)整SQL的順序,達到消除死鎖的目的混埠。
MySQL中的鎖
- X 排他鎖 與任何其他的鎖都是沖突的怠缸,其他的鎖需要等待
- S 共享鎖 與共享鎖可以兼容,如果有其他需要加共享鎖是可以進行的
已有鎖 \ 欲加鎖 | X (排它鎖) | S (共享鎖) |
---|---|---|
X(排它鎖) | 沖突 | 沖突 |
S(共享鎖) | 沖突 | 兼容 |
- 加鎖的方式:
- 外部加鎖:
- 由應用程序添加钳宪,鎖依賴關系較容易分析
- 共享鎖(S): select * from table lock in share mode
- 排它鎖(X): select * from table for update
- 內(nèi)部加鎖:
- 為了實現(xiàn)ACID特性揭北,由數(shù)據(jù)庫系統(tǒng)內(nèi)部自動添加
- 加鎖規(guī)則繁瑣,與SQL執(zhí)行計劃吏颖、事務隔離級別搔体、表索引結構有關
- 共享鎖(S)和排它鎖(X)
- 外部加鎖:
哪些SQL需要持有鎖
- 快照讀:
- Innodb 實現(xiàn)了多版本控制(MVCC),支持不加鎖快照讀
- Select * from table where ……
- 能夠保證同一個Select結果集是一致的
- 不能保證同一個事務內(nèi)部半醉,Select語句和其他語句的數(shù)據(jù)一致性疚俱,如果業(yè)務需要,需要通過外部顯示加鎖缩多。
- 當前讀:
- select * from table lock in share mode
- select * from table for update
- update from table set ……
- insert into ……
- delete from table ……
分析死鎖的常用辦法
-
show engine innodb status
分析死鎖