由Oracle觸發器死鎖及行級鎖限制所衍生的解決方案
這裡主要對前面觸發器死鎖那篇文章的具體化說明:
首先建立臨時表(session級)。
create global temporary table tilog(
rid urowid,
lock_flag,
update_flag,
tmstmp timestamp(6)) on commit preserve rows;
由於是session級的,且觸發器在內部不斷巢狀觸發過程中都是處於同一個session期。所以該臨時表適合於此種情況,而且適合於多併發的環境。
解決思路:
觸發器為update T表的時候觸發。觸發級別為for each row;
假設客戶編號C下面有A1、A2、A3三個帳號。
步驟1:當對T表執行update語句的時候,即已經鎖定了對應update所對應的行A1。此時,把對應的更新的這些行的rowid,鎖定標識(lock_flag=1),更新標識(update_flag=0),時間戳(cast(sysdate as timestamp))存放到臨時表tilog。
然後根據客戶編號,找到對應的其他賬戶編號(A2、A3)。並批次放入到陣列中(bulk collect into)。
步驟2:從陣列中迴圈取出一個賬戶編號A2,並從tilog中查詢該記錄的鎖定情況和更新情況。這裡對於A2,tilog中尚未存在該記錄。因此判斷為無鎖定和無更新。直接進入更新語句update。
步驟3:此時就又觸發了該觸發器,往tilog中插入A2的資訊(rowid,lock_flag=1,update_flag=0,timestamp)。然後再次由客戶編號得到A2外的兩個賬戶編號A1和A3。然後從tilog中查詢A1對應的鎖定和更新的資訊。由步驟1可得到對應A1目前處於鎖定狀態。因此不能執行update(否則造成死鎖)。因而迴圈到A3。A3的更新跟步驟相同。往tilog中插入對應鎖定和更新的資訊。
步驟4:A3觸發後進入觸發器的第三次觸發。此時根據A3從tilog中找到的A1和A2都是鎖定的記錄了。於是第三次觸發完成,跳出,執行commit,解除行鎖定標識並更新A3記錄的更新標識為1(標識該記錄已更新)。
步驟5:A3完成後,步驟3中對A2也進行commit及更新標識置1。然後回到步驟1。再次進入A3,從tilog中取出更新標識和鎖定標識。由於此時更新標識為1,即已更新。不再對該記錄進行處理。
步驟6:再次回到步驟1,更新A1記錄。此次觸發全過程完成。更新行鎖定標識為0及行更新標識為1。
下面是一個簡單的更新流程跟蹤:
c_fundacco=680760000029 islocked=0 isupdated=0
update->680760000029
c_fundacco=681850000091 islocked=1 isupdated=0
681850000091 is LOCKED!
c_fundacco=681850000079 islocked=0 isupdated=0
update->681850000079
c_fundacco=681850000091 islocked=1 isupdated=0
681850000091 is LOCKED!
c_fundacco=680760000029 islocked=1 isupdated=0
680760000029 is LOCKED!
c_fundacco=681000000027 islocked=0 isupdated=0
update->681000000027
c_fundacco=681850000091 islocked=1 isupdated=0
681850000091 is LOCKED!
c_fundacco=680760000029 islocked=1 isupdated=0
680760000029 is LOCKED!
c_fundacco=681850000079 islocked=1 isupdated=0
681850000079 is LOCKED!
commit[u]-unlock-updated->681000000027
commit[u]-unlock-updated->681850000079
c_fundacco=681000000027 islocked=0 isupdated=1
681000000027 is UPDATED!
commit[u]-unlock-updated->680760000029
c_fundacco=681850000079 islocked=0 isupdated=1
681850000079 is UPDATED!
c_fundacco=681000000027 islocked=0 isupdated=1
681000000027 is UPDATED!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12932950/viewspace-607753/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle觸發器死鎖問題解決Oracle觸發器
- SQ死鎖及死鎖的解決
- ORACLE ERP解決死鎖的方案Oracle
- Java 程式死鎖問題原理及解決方案Java
- 死鎖檢測及解決
- 解決Oracle死鎖的快捷方法Oracle
- mysql慢查詢,死鎖解決方案MySql
- oracle死鎖測試與解決Oracle
- 解決Oracle資料庫死鎖Oracle資料庫
- mysql之神奇的死鎖及解決思路MySql
- MySQL 死鎖解決MySql
- sqlserver大數批次update時死鎖的問題及解決方案SQLServer
- Oracle資料表死鎖的解決方法Oracle
- 解決Oracle死鎖問題步驟Oracle
- oracle 死鎖解決方法一例Oracle
- Oracle的TX鎖(行級鎖、事務鎖)Oracle
- oracle 死鎖表解決方法Oracle
- 常見的死鎖情況及解決方法
- MySQL 行級鎖的使用以及死鎖的預防MySql
- ORACLE死鎖及處理方式Oracle
- Oracle死鎖的檢視以及解決辦法Oracle
- oracle 死鎖Oracle
- ORA-00060死鎖的產生及解決
- oracle死鎖的檢視及kill方法Oracle
- 什麼是死鎖?如何解決死鎖?
- Oracle死鎖查詢及處理Oracle
- MySQL併發時經典常見的死鎖原因及解決方法MySql
- ORACLE 鎖機制及解決方法Oracle
- 殺死Oracle死鎖程式Oracle
- 檢視oracle死鎖程式並結束死鎖Oracle
- 鎖的種類,阻塞,死鎖產生與解決辦法。
- MySQL死鎖分析與解決之路MySql
- mysql行鎖和死鎖檢測MySql
- 分散式鎖的解決方案分散式
- 關於oracle的行級鎖Oracle
- 例項詳解 Java 死鎖與破解死鎖Java
- Oracle 死鎖處理Oracle
- Oracle死鎖處理Oracle