Oracle LOCK內部機制及最佳實踐系列(五)給出一個導致死鎖的SQL示例
給出一個導致死鎖的SQL示例。
死鎖定義:從廣義上講包括作業系統 應用程式 資料庫,如果2個程式(會話)相互持有對方的資源,都一直等待對方釋放,這種情況會造成死鎖。
誤解:會話的阻塞可不是死鎖,因為其中有一個會話還是可以繼續操作的。
釋放:Oracle會自動檢測死鎖並強制干預釋放
> create table p1 ( x int primary key ); 我們新建一個p1表,設定x欄位為主鍵
Table created.
> insert into leo1.p1 values(10); 138會話插入的是10
1 row created.
> insert into leo1.p1 values(20); 156會話插入的是20
1 row created.
> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
SID TYPE ID1 ID2 LMODE REQUEST BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
138 TM 73470 0 3 0 0
138 TX 327713 1124 6 0 0 138有一個TX排他鎖,但當前沒有阻塞會話
156 TM 73470 0 3 0 0
156 TX 589825 945 6 0 0 156也有一個TX排他鎖,但當前也沒有阻塞會話
> select object_name from dba_objects where object_id=73470; 看p1表上存在正常的TM TX鎖,都沒有阻塞到對方的會話
OBJECT_NAME
--------------------------------------------------------------------------------
P1
> insert into leo1.p1 values(20); 此時我在138會話上再插入20,發現hang住了不能前進,這是什麼原因呢?我們看看v$lock檢視
> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
138 TM 73470 0 3 0 0
138 TX 589825 945 0 4 0 這時138會話就繼續插入了,但這個插入動作是成功的沒有阻塞,而是由於138|156會話修改值的相同
138 TX 327713 1124 6 0 0 違反了主鍵約束從而產生阻塞,實際是對修改值的相同產生了阻塞,所以申請的是4級鎖,而非6級鎖
156 TM 73470 0 3 0 0
156 TX 589825 945 6 0 1 156會話此時正在阻塞138會話,因為156會話的事務還沒有完成還是一個未決狀態
> insert into leo1.p1 values(10); 我在156會話上也插入10,這時死鎖的效果就出來了
> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
138 TM 73470 0 3 0 0
138 TX 327713 1124 6 0 1 138會話此時正在阻塞156會話,因為138會話的事務還沒有完成還是一個未決狀態
156 TM 73470 0 3 0 0
156 TX 327713 1124 0 4 0 實際上是對修改值的相同產生了阻塞,156會話正在申請4級鎖
156 TX 589825 945 6 0 0
> insert into leo1.p1 values(20); 我們看一下138會話報錯,Oracle自動檢測死鎖並強制干預釋放
insert into leo1.p1 values(20)
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource(等待資源時檢測到死鎖->釋放之) 這時請注意一下,只是釋放掉了第一個鎖定,但第二個鎖定還在等待,所以我們要手工釋放
小結:上面講到了好幾種鎖的機制,我們崇尚的思想就是先要想一想為什麼會出現鎖,不出現行不行,鎖的作用有哪些,這種啟發式的思路能夠讓我們記憶深刻。
LOCK作用:獨佔業務資源 保證讀一致性 維護事務完整性
LOCK宗旨:沒有併發就沒有鎖,一個人運算元據庫是不會產生鎖的
2012.11.28
天津&winter
分享技術~成就夢想
Blog:
死鎖定義:從廣義上講包括作業系統 應用程式 資料庫,如果2個程式(會話)相互持有對方的資源,都一直等待對方釋放,這種情況會造成死鎖。
誤解:會話的阻塞可不是死鎖,因為其中有一個會話還是可以繼續操作的。
釋放:Oracle會自動檢測死鎖並強制干預釋放
> create table p1 ( x int primary key ); 我們新建一個p1表,設定x欄位為主鍵
Table created.
> insert into leo1.p1 values(10); 138會話插入的是10
1 row created.
> insert into leo1.p1 values(20); 156會話插入的是20
1 row created.
> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
SID TYPE ID1 ID2 LMODE REQUEST BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
138 TM 73470 0 3 0 0
138 TX 327713 1124 6 0 0 138有一個TX排他鎖,但當前沒有阻塞會話
156 TM 73470 0 3 0 0
156 TX 589825 945 6 0 0 156也有一個TX排他鎖,但當前也沒有阻塞會話
> select object_name from dba_objects where object_id=73470; 看p1表上存在正常的TM TX鎖,都沒有阻塞到對方的會話
OBJECT_NAME
--------------------------------------------------------------------------------
P1
> insert into leo1.p1 values(20); 此時我在138會話上再插入20,發現hang住了不能前進,這是什麼原因呢?我們看看v$lock檢視
> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
138 TM 73470 0 3 0 0
138 TX 589825 945 0 4 0 這時138會話就繼續插入了,但這個插入動作是成功的沒有阻塞,而是由於138|156會話修改值的相同
138 TX 327713 1124 6 0 0 違反了主鍵約束從而產生阻塞,實際是對修改值的相同產生了阻塞,所以申請的是4級鎖,而非6級鎖
156 TM 73470 0 3 0 0
156 TX 589825 945 6 0 1 156會話此時正在阻塞138會話,因為156會話的事務還沒有完成還是一個未決狀態
> insert into leo1.p1 values(10); 我在156會話上也插入10,這時死鎖的效果就出來了
> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
138 TM 73470 0 3 0 0
138 TX 327713 1124 6 0 1 138會話此時正在阻塞156會話,因為138會話的事務還沒有完成還是一個未決狀態
156 TM 73470 0 3 0 0
156 TX 327713 1124 0 4 0 實際上是對修改值的相同產生了阻塞,156會話正在申請4級鎖
156 TX 589825 945 6 0 0
> insert into leo1.p1 values(20); 我們看一下138會話報錯,Oracle自動檢測死鎖並強制干預釋放
insert into leo1.p1 values(20)
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource(等待資源時檢測到死鎖->釋放之) 這時請注意一下,只是釋放掉了第一個鎖定,但第二個鎖定還在等待,所以我們要手工釋放
小結:上面講到了好幾種鎖的機制,我們崇尚的思想就是先要想一想為什麼會出現鎖,不出現行不行,鎖的作用有哪些,這種啟發式的思路能夠讓我們記憶深刻。
LOCK作用:獨佔業務資源 保證讀一致性 維護事務完整性
LOCK宗旨:沒有併發就沒有鎖,一個人運算元據庫是不會產生鎖的
2012.11.28
天津&winter
分享技術~成就夢想
Blog:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26686207/viewspace-750184/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- WPF原始碼分析系列一:剖析WPF模板機制的內部實現(五)原始碼
- MySQL死鎖案例一(回滾導致死鎖)MySql
- mysql insert導致死鎖MySql
- WPF原始碼分析系列一:剖析WPF模板機制的內部實現(一)原始碼
- [20180801]insert導致死鎖.txt
- 【MySQL】Merge Index導致死鎖MySqlIndex
- pthread_once導致死鎖thread
- RocketMQ 重試機制詳解及最佳實踐MQ
- MySQL死鎖案例分析一(先delete,再insert,導致死鎖)MySqldelete
- MySQL死鎖案例二(自增列導致死鎖)MySql
- Mysql鎖機制與最佳化實踐以及MVCC底層原理剖析MySqlMVC
- ElasticSearch內部基於_version樂觀鎖控制機制Elasticsearch
- mysql同一個事務中update,insert導致死鎖問題分析解決MySql
- HBase內部機制
- redis 內部機制Redis
- RocketMQ 客戶端負載均衡機制詳解及最佳實踐MQ客戶端負載
- 最佳實踐|如何寫出簡單高效的 Flink SQL?SQL
- Sql Server深入的探討鎖機制SQLServer
- [轉帖]SQL Server 鎖機制 悲觀鎖 樂觀鎖 實測解析SQLServer
- TortoiseSvn強制解鎖 break lock
- 實施零信任網路訪問的五個最佳實踐
- 【鎖】Oracle鎖系列Oracle
- 【JavaSE】Lock鎖和synchronized鎖的比較,lock鎖的特性,讀寫鎖的實現。Javasynchronized
- ORACLE基礎之oracle鎖(oracle lock mode)詳解Oracle
- 14個Flink SQL效能最佳化實踐分享SQL
- Spring Boot中五個設計模式最佳實踐Spring Boot設計模式
- Linux核心同步機制之(五):Read Write spin lock【轉】Linux
- 使用 Wake Lock API:保持裝置喚醒的最佳實踐API
- 再談mysql鎖機制及原理—鎖的詮釋MySql
- Java併發程式設計之鎖機制之Lock介面Java程式設計
- 使用Java Optional類的最佳實踐 - oracleJavaOracle
- 京東雲TiDB SQL最佳化的最佳實踐TiDBSQL
- 探一探現代瀏覽器的內部機制(一)瀏覽器
- JavaScript 深入解剖bind內部機制JavaScript
- SQL Server Integration Services最佳實踐BTSQLServer
- 分散式鎖實現原理與最佳實踐分散式
- WebGPU 的幾個最佳實踐WebGPU
- oracle資料庫事務transaction鎖lock模式思考之一Oracle資料庫模式
- mysql innodb lock鎖之record lock之一MySql