原因:1、事務之間對資源存取順序的交替,兩個使用者互相存取了被對方鎖住的表產生死鎖;2、兩個使用者並發修改同一記錄產生死鎖;3 、執行了一條不符合條件的語句,索引不當導致全域掃描產生死鎖。
本教學操作環境:Windows10系統、Oracle 11g版、Dell G3電腦。
資料庫是一個多用戶使用的共享資源,當多個用戶並發地訪問資料時,在資料庫中就會產生多個事務同時訪問相同資料的情況。若對並發操作不加控制就可能會讀取和儲存不正確的數據,破壞資料庫的一致性。加鎖是實現資料庫並發控制的一個非常重要的技術。在實際應用中經常會遇到的與鎖相關的異常情況,當兩個事務需要一組有衝突的鎖,而不能將事務繼續下去的話,就會出現死鎖,嚴重影響應用的正常執行。
鎖定類型:
1、共享鎖定(Share Locks,即S鎖定):增加了共享鎖定的資料物件可以被其他交易讀取,但不能修改。資料庫利用這兩種基本的鎖定類型來對資料庫的事務進行並發控制。
2、排它鎖(Exclusive Locks,即X鎖定):當資料物件被加上排它鎖定時,其他的事務不能對它讀取和修改。
3、獨佔鎖定:在共享鎖定的基礎上,升級為獨佔鎖定。
4、更新鎖定:所有使用者都可以閱讀,但我將來可能會做更新操作,我已經獲取了從共享鎖定(用來讀)到排他鎖(用來更新)的資格。一個事物只能有一個更新鎖獲此資格。
出現原因:
1、事務之間對資源存取順序的交替:一個使用者1 存取表A(鎖定了表A),然後再訪問表B;另一用戶2 訪問表B(鎖定表B),然後企圖訪問表A;這時用戶1由於用戶2已經鎖定表B,它必須等待用戶2釋放表B才能繼續,同樣用戶2要等用戶1釋放表A才能繼續,這就死鎖就產生了。解決方案:程式邏輯問題、注意表的調用順序
2、並發修改同一記錄:用戶1查詢一條紀錄,然後修改該條紀錄;這時用戶2修改該條紀錄,這時用戶1的事務裡鎖的性質由查詢的共享鎖企圖上升到獨佔鎖,而用戶2裡的獨佔鎖由於1有共享鎖存在所以必須等1釋放掉共享鎖,而1由於2的獨佔鎖而無法上升的獨佔鎖定也不可能釋放共享鎖定,於是出現了死鎖 :
3、索引不當導致全表掃描:事務執行了一條不滿足條件的語句執行了全表掃描或表格資料量非常大索引建的過少或不合適的時候
解決方案:SQL語句中不要使用太複雜的關聯多表的查詢並建立索引進行最佳化
註:
1、oracle 查看死鎖並釋放死鎖
select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.locked_mode from v$locked_object lo, dba_objects ao, v$session sess where ao.object_id = lo.object_id and lo.session_id = sess.sid; alter system kill session '738,1429'; --释放资源
2、mysql 查看死鎖並釋放死鎖
show processlist --查看数据库中各个进程的运行状态 select * from information_schema.innodb_trx ---查询正在运行的事务 kill id
推薦教學:《Oracle影片教學》
以上是oracle死鎖的原因是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!