死鎖發生的情況一般是資源存在環形依賴。
oracle上的死鎖一般出現於「行級鎖」的環形依賴情況下:
有記錄a、b,事務t1、t2,現在t1、t2併發執行update(或delete)a+b
事務t1操作的順序為a-b,正常情況下會先後鎖住a和b
事務t2操作的順序為b-a,正常情況下會先後鎖住b和a
t1、t2併發執行,t1鎖住a 同時 t2鎖住b;
t1操作完a想要鎖住b,但b已被t2鎖住,t1等待中;t2操作完b想要鎖住a,但a已被t1鎖住,t2等待中;
由於t1、t2都在等待又都不釋放,因此造成死鎖。
當死鎖越來越多的時候,資料庫連線被耗盡,不再能接受新的連線;資料庫伺服器的cpu和記憶體也可能會不夠用了……程式猿就悲劇了。
解決辦法:
在事務開始時或開始前先對運算元據按統一規則排序。
例如:按a-b順序排序,使得t1、t2操作的順序都為a-b,假設t1、t2併發執行時t1鎖住了a;則t2只能等待a的鎖了,b就沒有機會被t2鎖住了;這樣t1就可以順利鎖住b,並順利執行;當t1執行完成,釋放a、b,t2就可以繼續執行了。
從線上死鎖的情況來看,主要發生在以下兩種場景:
在同乙個事務中無序的update或delete多條記錄,事務併發執行可能會有死鎖。
沒有事務,但執行單條update或delete sql時,如果update或delete所影響的記錄數大於1,也有可能出現死鎖。
對於第1種場景可以使用前述的解決辦法處理,即先排序後執行;
對於第2種場景的解決辦法如下:
先用select查詢出需要操作的記錄主鍵,按主鍵排序,再通過主鍵一條一條迭代執行。
不過將一條語句變成多條語句執行會破壞原有的事務(jdbc預設事務:一條sql語句即乙個事務),無法保證操作的原子性了,這就需要將這些操作放入乙個事務中。或者可以使用 in 語句將其改造成一條sql,例如:update ... where id in ( 1,2,3,4... ) ...,這樣效率會比多條sql語句高一些,而且 in 是可以命中索引的。
解決oracle死鎖
查哪個過程被鎖 查v db object cache檢視 select from v db object cache where owner 過程的所屬使用者 and locks 0 2.查是哪乙個sid,通過sid可知道是哪個session.查v access檢視 select from v ac...
oracle死鎖解決
自己實施測試成功步驟 a.查詢死鎖的使用者相關資訊 select s.username,l.object id,l.session id,s.serial l.oracle username,l.os user name,l.process from v locked object l,v sess...
如何解決Oracle死鎖問題
解決oracle死鎖問題步驟 出現問題 使用jdbc進行批量插入,一直卡在執行介面上,不走 預估應該是產生了死鎖 使用如下語句查詢oracle資料庫中的死鎖的表和死鎖型別 1 select b.owner,b.object name,a.session id,a.locked mode from v...