oracle中記錄被另一個用戶鎖住的原因與解決

原因:
數據庫是一個多用戶使用的共享資源。當多個用戶併發地存取數據時,在數據庫中就會產生多個事務同時存取同一數據的情況。若對併發操作不加控制就可能會讀取和存儲不正確的數據,破壞數據庫的一致性。

原理:

1.UPDATE/DELETE操作會將RS鎖定,直至操作被COMMIT或者ROLLBACK;
若操作未COMMIT之前其他session對同樣的RS做變更操作,則操作會被hold,直至前session的UPDATE/DELETE操作被COMMIT;

2.session內外SELECT的RS範圍
前提:INSERT、UPDATE操作未COMMIT之前進行SELECT;
若在同一session內,SELECT出來的RS會包括之前INSERT、UPDATE影響的記錄;
若不在同一session內,SELECT出來的RS不會包括未被COMMIT的記錄;

3.SELECT.... FOR UPDATE [OF cols] [NOWAIT/WAIT] [SKIP LOCKED]
OF cols:只鎖定指定字段所在表的RS,而沒有指定的表則不會鎖定,只會在多表聯合查詢時出現;
NOWAIT:語句不會hold,而是直接返回錯誤ORA-00054: resource busy and acquire with NOWAIT specified;
WAIT N:語句被hold N秒,之後返回錯誤ORA-30006: resource busy; acquire with WAIT timeout expired;
SKIP LOCKED:不提示錯誤,而是直接返回no rows selected;
以上幾個選項可以聯合使用的,比較推薦的有:
SELECT.... FOR UPDATE NOWAIT:對同一RS執行該SQL時,直接返回錯誤;
SELECT.... FOR UPDATE NOWAIT SKIP LOCKED:對同一RS執行該SQL時,直接返回空行;
PS:當RS被LOCK住之後,只對同樣請求LOCK的語句有效,對無需LOCK的SELECT語句並沒有任何影響;


解決辦法:


oracle數據中刪除數據時提示“記錄被另一個用戶鎖住” 解決方法:

1、查看數據庫鎖,診斷鎖的來源及類型:   select object_id,session_id,locked_mode from v$locked_object; 或者用以下命令: select b.owner,b.object_name,l.session_id,l.locked_mode from v$locked_object l, dba_objects b where b.object_id=l.object_id

2、找出數據庫的serial#,以備殺死:    select t2.username,t2.sid,t2.serial#,t2.logon_time from v$locked_object t1,v$session t2 where t1.session_id=t2.sid order by t2.logon_time;

3、殺死該session   alter system kill session 'sid,serial#'



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章