由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
- mysql慢查詢,死鎖解決方案MySql
- MySQL解決死鎖MySql
- MySQL 死鎖解決MySql
- 面試:什麼是死鎖,如何避免或解決死鎖;MySQL中的死鎖現象,MySQL死鎖如何解決面試MySql
- 常見的死鎖情況及解決方法
- 檢視oracle死鎖程式並結束死鎖Oracle
- 什麼是死鎖?如何解決死鎖?
- MySQL併發時經典常見的死鎖原因及解決方法MySql
- MySQL死鎖分析與解決之路MySql
- 分散式鎖的解決方案分散式
- mysql行鎖和死鎖檢測MySql
- Oracle死鎖一例(ORA-00060),鎖表導致的業務死鎖問題Oracle
- 例項詳解 Java 死鎖與破解死鎖Java
- SQL SERVER死鎖查詢,死鎖分析,解鎖,查詢佔用SQLServer
- 併發:死鎖
- Python | 多執行緒死鎖問題的巧妙解決方法Python執行緒
- LiteOS:SpinLock自旋鎖及LockDep死鎖檢測
- Oracle 0至6級鎖的通俗解釋及實驗案例Oracle
- oracle 查詢鎖 && 解鎖Oracle
- Oracle查詢鎖、解鎖Oracle
- 死鎖問題排查過程-間隙鎖的復現以及解決
- 記憶體混亂及解決方法和死鎖問題記憶體
- MySQL/InnoDB中,樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念的理解MySql
- 解決庫存扣減及訂單建立時防止併發死鎖的問題
- 執行緒中的死鎖執行緒
- 【Oracle】死鎖的產生與處理Oracle
- 自旋鎖、阻塞鎖、可重入鎖、悲觀鎖、樂觀鎖、讀寫鎖、偏向所、輕量級鎖、重量級鎖、鎖膨脹、物件鎖和類鎖物件
- 【分散式鎖的演化】常用鎖的種類以及解決方案分散式
- ORA-00060: Deadlock detected 模擬死鎖產生與解決方案
- Redis 分散式鎖解決方案Redis分散式
- Redis分散式鎖解決方案Redis分散式
- 作業系統(5) 死鎖的概念 死鎖產生的必要條件 死鎖的處理策略 預防死鎖 避免死鎖 死鎖的檢測和解除 銀行家演算法作業系統演算法
- Mysql使用kill命令解決死鎖問題MySql
- Redis分散式鎖(二):鎖超時後導致多個執行緒獲得鎖的解決方案Redis分散式執行緒
- 鎖的使用與死鎖的避免
- 死鎖
- (資料庫十)資料庫中的鎖機制以及死鎖產生的原因及解決辦法資料庫
- [C#.NET 拾遺補漏]12:死鎖和活鎖的發生及避免C#