模擬insert,update和delete造成阻塞的示例
會話1SID
BYS@dg2>select distinct sid from v$mystat;
SID
----------
17
會話2SID
BYS@dg2>select distinct sid from v$mystat;
SID
----------
49
insert造成阻塞的示例
在會話1向表T插入一條資料值1,因為插入資料所在欄位有主鍵約束。
此時會話1不提交或回滾插入操作時,在會話2進行同樣的向表T插入一條資料值1時被髮生阻塞,語句無法執行。
此時再開啟一個會話,可以從v$lock檢視中查詢出有鎖的表及所在會話ID。
會話1:
BYS@dg2>create table t(x number primary key);---新建表,設定主鍵
Table created.
BYS@dg2>insert into t values(1); --插入資料不提交
1 row created.
BYS@dg2>
會話2:此時執行插入相同數值時被阻塞----hang住。
BYS@dg2>insert into t values(1);
如果會話1提交,阻塞中止,此時會話2語句執行並報錯,提示違反了主鍵的一致性約束
BYS@dg2>insert into t values(1);
insert into t values(1)
*
ERROR at line 1:
ORA-00001: unique constraint (BYS.SYS_C0011300) violated
會話3:
SID:會話id號
TYPE:鎖的型別
ID1:會話操作物件的id號
ID2:ID1+ID2 定位回滾段上的一個地址(即修改之前資料映象地址),由於138和156會話是一樣的說明指向的是同一個地址,換句話說操作的是同一行資料
LMODE:鎖模式,不同的數字代表不同的鎖模式 例如 0 現在沒有申請到鎖 3 共享鎖模式(段級共享鎖) 6 排他鎖模式 鎖的級別越高限制越多
REQUEST:目前會話沒有鎖,正在申請的鎖模式 例如 0 沒有正在申請的鎖,說明已經有鎖了 6 現在正在申請6號鎖,目前因為沒有才申請
BLOCK:當前正在阻塞幾個會話 例如 1 當前正在阻塞一個會話 2 當前正在阻塞兩個會話
鎖的實質:是維護一個事務完整性的,鎖的資訊是資料塊的一個屬性,是物理的,並不是邏輯上屬於某個表或者某幾行的。
BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
49 TX 65562 824 0 4 0 --插入的修改值相同才被阻塞,鎖級別是4
49 TM 75052 0 3 0 0
17 TM 75052 0 3 0 0
49 TX 327706 1041 6 0 0 --49號會話插入第二條記錄未被阻塞
17 TX 65562 824 6 0 1 -----正在阻塞一個會話
BYS@dg2>select sid,event from v$session_wait where sid in (49,17);
SID EVENT
---------- ----------------------------------------------------------------
17 SQL*Net message from client
49 enq: TX - row lock contention
insert時v$lock檢視裡面多了一個TX鎖(就是最後一行)。
insert和update delete操作的不同,後兩者都是對同一條記錄的修改權爭用產生阻塞(這裡不涉及修改值的問題),
而insert操作實際上插入了2條不同的記錄,由於這2條不同的記錄的修改值一樣違反了主鍵約束從而產生阻塞,實際是對修改值的相同產生了阻塞。鎖的級別為4,這種鎖比update的鎖級別要低,鎖的級別越低限制越少。
#####################################################
update造成阻塞的示例
會話1:
BYS@dg2>update t set x=2 where x=1;
1 row updated.
BYS@dg2>
會話二:
BYS@dg2>update t set x=3 where x=1;
會話3
BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
49 TX 196624 1041 0 6 0
49 TM 75052 0 3 0 0
17 TM 75052 0 3 0 0
17 TX 196624 1041 6 0 1
BYS@dg2>select sid,event from v$session_wait where sid in (49,17);
SID EVENT
---------- ----------------------------------------------------------------
17 SQL*Net message from client
49 enq: TX - row lock contention
BYS@dg2>col object_name for a20
BYS@dg2>select object_name from dba_objects where object_id=75052;
OBJECT_NAME
--------------------
T
說明 :17會話在T表加了TM TX鎖。TM鎖模式為3--共享鎖 TX鎖模式為6--排它鎖。
目前TX鎖正在阻塞一個會話-49 可以在49的行看到它在請求一個模式為6的鎖。
49會話是當前被阻塞的會話,它操作的物件也是T表(從ID1看)。
TM鎖模式也為3(共享鎖是有幾個會話就可以建立幾個共享鎖,同時存在).
此時它正在申請17會話所持有的模式為6的鎖(操作同一行資料)。
delete造成阻塞的示例
會話1:
BYS@dg2>delete from t; 17會話在刪除表內記錄-只有一條。未提交,加了TM TX鎖
1 row deleted.
會話2:
BYS@dg2>delete from t; 此時在49會話也進行刪除表內記錄,hang住
會話3:
BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
49 TX 262145 912 0 6 0 --被阻塞了正在申請一個模式6的鎖
49 TM 75052 0 3 0 0
17 TM 75052 0 3 0 0
17 TX 262145 912 6 0 1 持有模式6鎖,阻塞一個會話
BYS@dg2>select sid,event from v$session_wait where sid in (49,17);
SID EVENT
---------- ----------------------------------------------------------------
17 SQL*Net message from client
49 enq: TX - row lock contention
49會話因TX鎖爭用導致hang,enq=enqueues佇列鎖
#####################
select...for update 鎖阻塞 這是一種對結果集修改的保護機制
場景:一次性修改多條記錄的時候會用到這個命令,起到鎖定結果集的效果,這也是結果集修改引起的阻塞
會話1:
BYS@dg2>select * from t where x=2 for update; 對查詢出的結果集進行獨佔,此時不允許其他會話進行修改
X
----------
2
會話2:
BYS@dg2>select * from t where x=2 for update;
會話3:
BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
49 TX 589852 1023 0 6 0
49 TM 75052 0 3 0 0
17 TM 75052 0 3 0 0
17 TX 589852 1023 6 0 1
17號會話阻塞49號會話。這種方法可以一次鎖定多行記錄。一個表上只能有一個6號鎖。
BYS@dg2>select sid,event from v$session_wait where sid in (49,17);
SID EVENT
---------- ----------------------------------------------------------------
17 SQL*Net message from client
49 enq: TX - row lock contention
BYS@dg2>select distinct sid from v$mystat;
SID
----------
17
會話2SID
BYS@dg2>select distinct sid from v$mystat;
SID
----------
49
insert造成阻塞的示例
在會話1向表T插入一條資料值1,因為插入資料所在欄位有主鍵約束。
此時會話1不提交或回滾插入操作時,在會話2進行同樣的向表T插入一條資料值1時被髮生阻塞,語句無法執行。
此時再開啟一個會話,可以從v$lock檢視中查詢出有鎖的表及所在會話ID。
會話1:
BYS@dg2>create table t(x number primary key);---新建表,設定主鍵
Table created.
BYS@dg2>insert into t values(1); --插入資料不提交
1 row created.
BYS@dg2>
會話2:此時執行插入相同數值時被阻塞----hang住。
BYS@dg2>insert into t values(1);
如果會話1提交,阻塞中止,此時會話2語句執行並報錯,提示違反了主鍵的一致性約束
BYS@dg2>insert into t values(1);
insert into t values(1)
*
ERROR at line 1:
ORA-00001: unique constraint (BYS.SYS_C0011300) violated
會話3:
SID:會話id號
TYPE:鎖的型別
ID1:會話操作物件的id號
ID2:ID1+ID2 定位回滾段上的一個地址(即修改之前資料映象地址),由於138和156會話是一樣的說明指向的是同一個地址,換句話說操作的是同一行資料
LMODE:鎖模式,不同的數字代表不同的鎖模式 例如 0 現在沒有申請到鎖 3 共享鎖模式(段級共享鎖) 6 排他鎖模式 鎖的級別越高限制越多
REQUEST:目前會話沒有鎖,正在申請的鎖模式 例如 0 沒有正在申請的鎖,說明已經有鎖了 6 現在正在申請6號鎖,目前因為沒有才申請
BLOCK:當前正在阻塞幾個會話 例如 1 當前正在阻塞一個會話 2 當前正在阻塞兩個會話
鎖的實質:是維護一個事務完整性的,鎖的資訊是資料塊的一個屬性,是物理的,並不是邏輯上屬於某個表或者某幾行的。
BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
49 TX 65562 824 0 4 0 --插入的修改值相同才被阻塞,鎖級別是4
49 TM 75052 0 3 0 0
17 TM 75052 0 3 0 0
49 TX 327706 1041 6 0 0 --49號會話插入第二條記錄未被阻塞
17 TX 65562 824 6 0 1 -----正在阻塞一個會話
BYS@dg2>select sid,event from v$session_wait where sid in (49,17);
SID EVENT
---------- ----------------------------------------------------------------
17 SQL*Net message from client
49 enq: TX - row lock contention
insert時v$lock檢視裡面多了一個TX鎖(就是最後一行)。
insert和update delete操作的不同,後兩者都是對同一條記錄的修改權爭用產生阻塞(這裡不涉及修改值的問題),
而insert操作實際上插入了2條不同的記錄,由於這2條不同的記錄的修改值一樣違反了主鍵約束從而產生阻塞,實際是對修改值的相同產生了阻塞。鎖的級別為4,這種鎖比update的鎖級別要低,鎖的級別越低限制越少。
#####################################################
update造成阻塞的示例
會話1:
BYS@dg2>update t set x=2 where x=1;
1 row updated.
BYS@dg2>
會話二:
BYS@dg2>update t set x=3 where x=1;
會話3
BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
49 TX 196624 1041 0 6 0
49 TM 75052 0 3 0 0
17 TM 75052 0 3 0 0
17 TX 196624 1041 6 0 1
BYS@dg2>select sid,event from v$session_wait where sid in (49,17);
SID EVENT
---------- ----------------------------------------------------------------
17 SQL*Net message from client
49 enq: TX - row lock contention
BYS@dg2>col object_name for a20
BYS@dg2>select object_name from dba_objects where object_id=75052;
OBJECT_NAME
--------------------
T
說明 :17會話在T表加了TM TX鎖。TM鎖模式為3--共享鎖 TX鎖模式為6--排它鎖。
目前TX鎖正在阻塞一個會話-49 可以在49的行看到它在請求一個模式為6的鎖。
49會話是當前被阻塞的會話,它操作的物件也是T表(從ID1看)。
TM鎖模式也為3(共享鎖是有幾個會話就可以建立幾個共享鎖,同時存在).
此時它正在申請17會話所持有的模式為6的鎖(操作同一行資料)。
delete造成阻塞的示例
會話1:
BYS@dg2>delete from t; 17會話在刪除表內記錄-只有一條。未提交,加了TM TX鎖
1 row deleted.
會話2:
BYS@dg2>delete from t; 此時在49會話也進行刪除表內記錄,hang住
會話3:
BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
49 TX 262145 912 0 6 0 --被阻塞了正在申請一個模式6的鎖
49 TM 75052 0 3 0 0
17 TM 75052 0 3 0 0
17 TX 262145 912 6 0 1 持有模式6鎖,阻塞一個會話
BYS@dg2>select sid,event from v$session_wait where sid in (49,17);
SID EVENT
---------- ----------------------------------------------------------------
17 SQL*Net message from client
49 enq: TX - row lock contention
49會話因TX鎖爭用導致hang,enq=enqueues佇列鎖
#####################
select...for update 鎖阻塞 這是一種對結果集修改的保護機制
場景:一次性修改多條記錄的時候會用到這個命令,起到鎖定結果集的效果,這也是結果集修改引起的阻塞
會話1:
BYS@dg2>select * from t where x=2 for update; 對查詢出的結果集進行獨佔,此時不允許其他會話進行修改
X
----------
2
會話2:
BYS@dg2>select * from t where x=2 for update;
會話3:
BYS@dg2>select sid,type,id1,id2,lmode,request,block from v$lock where type in('TM','TX');
SID TY ID1 ID2 LMODE REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
49 TX 589852 1023 0 6 0
49 TM 75052 0 3 0 0
17 TM 75052 0 3 0 0
17 TX 589852 1023 6 0 1
17號會話阻塞49號會話。這種方法可以一次鎖定多行記錄。一個表上只能有一個6號鎖。
BYS@dg2>select sid,event from v$session_wait where sid in (49,17);
SID EVENT
---------- ----------------------------------------------------------------
17 SQL*Net message from client
49 enq: TX - row lock contention
相關文章
- 利用insert,update和delete注入獲取資料delete
- sql server 帶有OUTPUT的INSERT,DELETE,UPDATESQLServerdelete
- SQLite語句(二):INSERT DELETE UPDATE SELECTSQLitedelete
- mysql 在delete、insert、update 時,page的變化MySqldelete
- java-Mybatis XML 對映器(select,insert, update 和 delete)JavaMyBatisXMLdelete
- DBeaver如何生成select,update,delete,insert語句delete
- KunlunDB功能之insert/update/delete...returning語句delete
- SQL Server的Merge —— 一步實現 insert,update,deleteSQLServerdelete
- 輕量ORM-SqlRepoEx (四)INSERT、UPDATE、DELETE 語句ORMSQLdelete
- MyBatis(五) insert、update、delete 、主鍵回填、返回matched行數和affected行數、引數配置#{},${}MyBatisdelete
- Oracle中 Update和insert結合語法Oracle
- Sqlserver、oracle中Merge的使用方法,一個merge語句搞定多個Insert,Update,Delete操作SQLServerOracledelete
- sipp模擬uas傳送update
- 管理工具造成的阻塞
- 380. Insert Delete GetRandom O (1)deleterandom
- Hive學習筆記 ---- 支援Update和Delete以及MergeHive筆記delete
- [LeetCode] 380. Insert Delete GetRandom O(1)LeetCodedeleterandom
- mysql update join,insert select 語法MySql
- MySQL insert on duplicate key update 死鎖MySql
- 單表的更新UPDATE和刪除記錄DELETE(二十六)delete
- Sqlserver update\delete用inner join關聯,會update\delete關鍵字後面的表關聯到的行SQLServerdelete
- MySQL 關於 INSERT INTO...ON DUPLICATE KEY UPDATE 的使用MySql
- mybatis 批量新增insert、更新update詳解MyBatis
- 模擬資料支援post, put, delete等http方式deleteHTTP
- 資料庫自動收縮造成的阻塞資料庫
- 為什麼sleeping的會話會造成阻塞會話
- BUG: pymysql executemany不支援insert on duplicate key updateMySql
- MySQL資料災難挽救之Delete\UpdateMySqldelete
- 用ASP.NET Core 2.0 建立規範的 REST API -- DELETE, UPDATE, PATCH 和 LogASP.NETRESTAPIdelete
- 為什麼sleeping的會話會造成阻塞(2)會話
- mssql sqlserver update delete表別名用法簡介SQLServerdelete
- insert all和insert first語句的用法
- Oracle中的for update 和 for update nowaitOracleAI
- ORACLE RAC叢集大範圍delete大表與insert&update同時執行導致活動會話數飆升Oracledelete會話
- 比CRUD多一點兒(三):UPDATE、DELETE語句delete
- Python 使用socket模擬http請求,從阻塞到協程PythonHTTP
- MySQL死鎖案例分析一(先delete,再insert,導致死鎖)MySqldelete
- Thinkphp 3.2.3 parseWhere設計缺陷導致update/delete注入 分析PHPdelete
- PostgreSQL模擬兩個update語句死鎖-利用掃描方法SQL