zoukankan      html  css  js  c++  java
  • Oracle死锁

    所有的死锁应该都是类似的.比如二个人在走廊相遇,每个人都打招呼都会点头,抬头二个动作.如果对方不抬头自己也不抬头.如果二个人同时低头,就会都等待对方抬头,这就是死锁的场景.

    ----------------------------------------------------

    ORACLE鎖具體分為以下幾類:
    1.按用戶與系統劃分,可以分為自動鎖與顯示鎖
    自動鎖:當進行一項數據庫操作時,缺省情況下,系統自動為此數據庫操作獲得所有有必要的鎖。
    顯示鎖:某些情況下,需要用戶顯示的鎖定數據庫操作要用到的數據,才能使數據庫操作執行得更好,顯示鎖是用戶為數據庫對像設定的。
    2.按鎖級別劃分,可分為共享鎖與排它鎖
    共享鎖:共享鎖使一個事務對特定數據庫資源進行共享訪問——另一事務也可對此資源進行訪問或獲得相同共享鎖。共享鎖為事務提供高並發性,但如拙劣的事務設計+共享鎖容易造成死鎖或數據更新丟失。
    排它鎖:事務設置排它鎖後,該事務單獨獲得此資源,另一事務不能在此事務提交之前獲得相同對象的共享鎖或排它鎖。
    3.按操作劃分,可分為DML鎖、DDL鎖
    +DML鎖又可以分為,行鎖、表鎖、死鎖
    -行鎖:當事務執行數據庫插入、更新、刪除操作時,該事務自動獲得操作 表中操作行的排它鎖。
    - 表級鎖:當事務獲得行鎖後,此事務也將自動獲得該行的表鎖(共享鎖),以 防止其它事務進行DDL語句影響記錄行的更新。事務也可以在進行 過程中獲得共享鎖或排它鎖,只有當事務顯示使用LOCK TABLE語 句顯示的定義一個排它鎖時,事務才會獲得表上的排它鎖,也可使用
    LOCK TABLE顯示的定義一個表級的共享鎖(LOCK TABLE具體用法請參 考相關文檔)。
    -死鎖:當兩個事務需要一組有衝突的鎖,而不能將事務繼續下去的話,就 出現死鎖。
    如事務1在表A行記錄#3中有一排它鎖,並等待事務2在表A中記錄#4 中排它鎖的釋放,而事務2在表A記錄行#4中有一排它鎖,並等待事務 1在表A中記錄#3中排它鎖的釋放,事務1與事務2彼此等待,因此就造 成了死鎖。死鎖一般是因拙劣的事務設計而產生。

    對於查詢哪些人或進程被鎖使用如下SQL:

    SELECT OBJECT_ID,SESSION_ID,SERIAL# ,a.oracle_username,a.os_user_name,a.process
     FROM V$LOCKED_OBJECT a ,
    V$SESSION  WHERE a.SESSION_ID=SID;

    解鎖能使用SQL下:alter system kill session 'sid,serial#';
    或者使用相關操作系統kill進程的命令,如UNIX下kill -9 sid,或者 使用其它工具殺掉死鎖進程。
    +DDL鎖又可以分為:排它DDL鎖、共享DDL鎖、分析鎖
    -排它DDL鎖:創建、修改、刪除一個數據庫對象的DDL語句獲得操作對象的 排它鎖。
    如使用alter table語句時,為了維護數據的完成性、一致性、
    合法性,該事務獲得一排它DDL鎖。
    -共享DDL鎖:需在數據庫對像之間建立相互依賴關係的DDL語句通常需共享
    獲得DDL鎖。
    如創建一個包,該包中的過程與函數引用了不同的數據庫表,
    當編譯此包時,該事務就獲得了引用表的共享DDL鎖。
    -分析鎖:ORACLE使用共享池存儲分析與優化過的SQL語句及PL/SQL程序,使
    運行相同語句的應用速度更快。一個在共享池中緩存的對象獲得
    它所引用數據庫對象的分析鎖。分析鎖是一種獨特的DDL鎖類型,
    ORACLE使用它追蹤共享池對象及它所引用數據庫對像之間的依賴 關係。當一個事務修改或刪除了共享池持有分析鎖的數據庫對像
    時,ORACLE使共享池中的對象作廢,下次在引用這條SQL/PLSQL語 句時,ORACLE重新分析編譯此語句。
    4.內部閂鎖
    內部閂鎖:這是ORACLE中的一種特殊鎖,用於順序訪問內部系統結構。
    當事務需向緩衝區寫入信息時,為了使用此塊內存區域, ORACLE首先必須取得這塊內存區域的閂鎖,才能向此塊內存寫入信息。

    ----------------------------------------------------

    转自http://inshua.iteye.com/blog/882613

    某服务器经常在执行批量更新时出现如下死锁错误,然后假死。作为一个正常的服务器,出错是允许的,假死是不允许的。

    Java代码  收藏代码
    1. java.sql.BatchUpdateException: ORA-00060: deadlock detected while waiting for resource  
    2.   
    3.     at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)  
    4.     at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10656)  
    5.     at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)  



    这个问题很难重现。要解决此问题,先要能让它重现。野蛮的重现方法因多个服务器不能同时复盘故不可取,只有知道原因才好重现。

    ora-60 错误是很有名的错误,google 到重现方法:

    引用

    两个session进入事务

    session 1   update a
    session 2   update b
    session 1   update b  (session 1 等待)
    session 2   update a  (session 1 出错)


    此外,还有一种这样的路径:

    引用

    两个session进入事务

    session 1   update a
    session 2   update b
    session 2   update a  (session 2 等待)
    session 1   update b  (session 2 出错)


    结论: 谁等待谁出错。

    原理:等待者已申请的资源被先占者申请,先占者将抢到该资源,oracle 即通知等待者其申请作废。ora-60 错误就是这样一个通知。

    可见,前面那个服务器有做等待。

    然而,该 BatchUpdate 只操作一个表,不可能出现上面的等待。

    通过翻阅  /product/app/oracle/admin/xxx/udump 中的 trace 信息,发现等待者和抢占者的语句均指向同一个表。两个session操作单表也可以死锁?

    什么原因,忽然想到,行级锁!

    原来,两个更新事务,彼此都在更新同一张表,假如都命中了 1、3 两行,一个按 1、3 次序命中,一个按 3、1 次序命中,就会出现上述错误了。

    更小的试验是这样进行的:

    引用

    两个session进入事务

    session 1   update a(1)
    session 2   update a(3)
    session 1   update a(3)  (session 1 等待)
    session 2   update a(1)  (session 1 出错)


    按此试验结果,在服务器中重现了该错误。

    经重现后发现,假死原因是在使用连接池时,close(ps) 后再 prepareStatement().executeBatch 就会出现卡壳。

    解决方法:在 BatchUpdateExcetion 后,应使用 ps.cancel() 释放 PrepareStatement 的事务。

    再次试验问题得到解决。效果如何正在观察。
  • 相关阅读:
    机械键盘与选购技巧
    计算机科学与技术专业的知识架构
    加法器
    计算机底层逻辑电路
    小数在计算机的表示
    整数在计算机里的表示
    Core ML 机器学习
    MapFileParser.sh: Permission denied
    iOS开发创建UI的耗时操作处理
    iOS application/json上传文件等
  • 原文地址:https://www.cnblogs.com/highriver/p/2006684.html
Copyright © 2011-2022 走看看