如果有两个会话,每个会话都持有另一个会话想要的资源,此时就会发生死锁。
用下面实验来说明死锁的产生原因和解决办法。
SESSION1:
SQL> create table t2 as select * from emp;
SQL> select * from t2 where empno=7369;

EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217 00:00:00        800                    20

SQL> update t2 set sal=sal+200 where empno=7369;

SQL> select * from t2 where empno=7369;

EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217 00:00:00       1000                    20

SESSION2:

SQL> select * from t2 where empno=7900;

EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7900 JAMES      CLERK           7698 19811203 00:00:00        950                    30

SQL> update t2 set sal=sal+200 where empno=7900;

1 row updated.

SQL> select * from t2 where empno=7900;

EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7900 JAMES      CLERK           7698 19811203 00:00:00       1150                    30

SESSION1:
SQL> select * from t2 where empno=7900;

EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7900 JAMES      CLERK           7698 19811203 00:00:00        950                    30

SESSION2:
SQL> select * from t2 where empno=7369;

EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217 00:00:00        800                    20

SESSION1:
SQL> update t2 set sal=sal-200 where empno=7900; 
出现等待

SESSION2:
SQL> update t2 set sal=sal-200 where empno=7369;
死锁发生,session2被阻塞
系统回滚session1跟死锁有关的sql。
update t2 set sal=sal-200 where empno=7900
       *
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource

SESSION1:
SQL> select * from t2 where empno in (7369,7900);

EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217 00:00:00       1000                    20
      7900 JAMES      CLERK           7698 19811203 00:00:00        950                    30
看到系统只回滚了对empno=7900的修改。
而此时SESSION2的update t2 set sal=sal-200 where empno=7369;依然被SESSION1的第一条语句所阻塞。

我们现在查看产生锁的情况
打开第三个会话以DBA身份登录
SQL> select * from v$lock;

ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
29434224 29434238        165 XR          4          0          1          0       2998          0
29434280 29434294        165 CF          0          0          2          0       2988          0
294342DC 294342F0        167 PW          1          0          3          0       2980          0
29434338 2943434C        165 RS         25          1          2          0       2983          0
294343F0 29434404        166 RT          1          0          6          0       2983          0
2943444C 29434460        153 TX     589868        325          0          4         24          0
29434560 29434574        167 MR          1          0          4          0       2983          0
294345BC 294345D0        167 MR          2          0          4          0       2983          0
29434618 2943462C        167 MR          3          0          4          0       2983          0
29434674 29434688        167 MR          4          0          4          0       2983          0
294346D0 294346E4        167 MR          5          0          4          0       2983          0
2943472C 29434740        167 MR          6          0          4          0       2983          0
29434788 2943479C        167 MR          7          0          4          0       2983          0
294347E4 294347F8        167 MR        201          0          4          0       2983          0
2943489C 294348B0        164 TS          3          1          3          0       2979          0
288F6030 288F6048        144 TM      53257          0          3          0         51          0
288F60DC 288F60F4        153 TM      53257          0          3          0         24          0
28934170 28934194        153 TX     655363        241          6          0         24          0
28969404 28969428        144 TX     589868        325          6          0         51          1

19 rows selected.

用下面的SQL语句可以直接得出谁阻塞谁
SQL> select ( select username from v$session where sid=a.sid) blocker, a.sid,
        ' is blocking ',
        (select username from v$session where sid=b.sid) blockee, b.sid
from v$lock a, v$lock b
where a.block=1 and b.request>0 and a.id1=b.id1 and a.id2=b.id2;

BLOCKER                               SID 'ISBLOCKING'  BLOCKEE                               SID
------------------------------ ---------- ------------- ------------------------------ ----------
STONE                                 144  is blocking  STONE                                 153

发生死锁的时候会在alert文件里记录下信息。
--查看操作系统下$ORACLE_BASE/admin/orcl/bdump/alert_orcl.log文件,会找到如下信息
Thu Sep  2 20:41:25 2010
ORA-00060: Deadlock detected. More info in file /u01/app/oracle/admin/orcl/udump/orcl_ora_4945.trc.

再查看跟踪文件详细信息
*** 2010-09-02 20:41:25.700
*** ACTION NAME () 2010-09-02 20:41:25.699
*** MODULE NAME (SQL*Plus) 2010-09-02 20:41:25.699
*** SERVICE NAME (SYS$USERS) 2010-09-02 20:41:25.699
*** SESSION ID (144.3) 2010-09-02 20:41:25.699
DEADLOCK DETECTED ( ORA-00060 )
[Transaction Deadlock]
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:
                       ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TX-00090015-00000146        19     144     X             23     148           X
.......

SESSION2还在被SESSION1阻塞,只有在SESSION1执行提交或回退才能让SESSION2继续下去。
SESSION1:
commit; --将提交update t2 set sal=sal+200 where empno=7369的修改

rollback;--将取消update t2 set sal=sal+200 where empno=7369的修改

随即SESSION2得到1 row updated.的信息。

我们也可以用管理员账号执行kill命令杀死导致阻塞的会话SESSION1来解决死锁。
sqlplus / as sysdba
从上面查过的信息可以知道产生阻塞的sid=144
通过查v$session视图可以得出serial#

SADDR           SID    SERIAL#     AUDSID PADDR         USER# USERNAME       COMMAND    OWNERID TADDR
-------- ---------- ---------- ---------- -------- ---------- ----------- ---------- ---------- -----
29F0BED4        144          3     210009 29E24174         64 STONE                0 2147483644

杀死这个会话用下面的命令
alter system kill session '144,3';

总结:
    Oralce认为死锁是应用导致的错误,Oracle中很少出现死锁。导致死锁的的头号杀手是外键没有加索引,第二号杀手则是位图索引遭到并发更新。
    如果外键没有索引,我们更新了父表的主键时将会锁住整个子表。如果外键没有索引,删除了父表中的一行,整个子表也会被锁住。这样就很容易产生很多问题,如果其中任何阻塞的会话锁住了某一会话需要的资源就会出现一个死锁。至于位图索引的并发更新,是会锁住所有相关联的行,也会导致问题的发生。
    在Oracle9i及以上版本中,这些全表锁都是短期的,也就是仅在DML操作期间存在,而不是存在于整个事务期间。

本文转自:http://www.itpub.net/thread-1347577-1-1.html

Oracle死锁产生的原因和解决办法的更多相关文章

  1. mysql数据库死锁的产生原因及解决办法

    这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下   数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同 ...

  2. Oracle常见死锁发生的原因以及解决方法

    Oracle常见死锁发生的原因以及解决办法 一,删除和更新之间引起的死锁 造成死锁的原因就是多个线程或进程对同一个资源的争抢或相互依赖.这里列举一个对同一个资源的争抢造成死锁的实例. Oracle 1 ...

  3. ORA-00907: 缺失右括号,原因及解决办法整理

    ORA-00907: 缺失右括号,原因及解决办法整理 1 union all中order by 导致缺失右括号 在有union all的子查询中使用了order by,会导致缺失右括号的错误,事实上在 ...

  4. jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法

    jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法   在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...

  5. java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver 错误的解决办法

    java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver 错误的解决办法 (2011-05-05 16:08:05) 转载▼ ...

  6. 各种编码问题产生原因以及解决办法---------响应编码,请求编码,URL编码

     响应编码 产生原因以及解决办法: 示例: package cn.yzu; import java.io.IOException; import javax.servlet.ServletExcept ...

  7. .Net内存泄露原因及解决办法

    .Net内存泄露原因及解决办法 1.    什么是.Net内存泄露 (1).NET 应用程序中的内存 您大概已经知道,.NET 应用程序中要使用多种类型的内存,包括:堆栈.非托管堆和托管堆.这里我们需 ...

  8. HttpClient的CircularRedirectException异常原因及解决办法

    HttpClient的CircularRedirectException异常原因及解决办法 这两天在使用我自己爬虫抓取网页的时候总是出现 org.apache.http.client.ClientPr ...

  9. php_curl.dll libssh2.dll 始终无法加载的原因 及解决办法

    在StackOverflow得到最终原因及解决办法 http://stackoverflow.com/questions/16424117/php-unable-to-load-php-curl-dl ...

随机推荐

  1. 使用实时文件夹显示ContentProvider的数据

    所谓实时文件夹(即LiveFolder),是指用于显示ContentProvider提供的数据的桌面组件. ContentProvider用于向外提供数据访问的接口,一个应用程序可通过ContentP ...

  2. kvm虚拟机安装

    KVM虚拟化技术介绍 概述 KVM是基于内核的虚拟化技术(Kernel-based Virtual Machine),于2007年的Linux 2.6.20被合并进Linux内核.KVM要求CPU支持 ...

  3. Node.js 函数

    Node.js 函数 在JavaScript中,一个函数可以作为另一个函数接收一个参数.我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数. Node.js中函数的使用与Javasc ...

  4. win7 下设置时间格式为yyyy-MM-dd 格式无效的解决方法

    部分win7 64位机器,在时间区域部分设置了时间格式为:yyyy-MM-dd后程序和数据库里面还是原来默认的yyyy/MM/dd格式 打开注册表,搜索 yyyy/MM/dd ,修改为yyyy-MM- ...

  5. Java String.split()用法小结

    在java.lang包中有String.split()方法,返回是一个数组 我在应用中用到一些,给大家总结一下,仅供大家参考: 1.如果用“.”作为分隔的话,必须是如下写法,String.split( ...

  6. Android中Handler的消息处理

    关于Handler机制,能找到无数的文章.http://blog.csdn.net/jiangshitian/article/details/12525313这篇博客写得比较好,关键是图很清晰,结合H ...

  7. Android TextView里显示两种颜色

    今天介绍一个小技巧,在Android的TextView里设置两种颜色,直接上代码: TextView TV = (TextView)findViewById(R.id.mytextview01); S ...

  8. OMG点菜系统

    算是一个项目吧,自己一个人也写了很久,有很多东西是自己写的,当然也有在网上借鉴人家大神的,不一而足,代码太多,不贴了,直接上图.(一直出现的天蓝色是使用windows自带主题壁纸上截取的一段) [原本 ...

  9. win7下用python3.3获取cable modem的设备信息

    毕业一年多了,一直做cable modem的测试,总是觉得在国内这一行的人才很少,想找个师傅真的很不容易. 苦闷了许久之后,终于决定,自己去写点东西,万一就找到同行了呢? 下面就是本小姐写的第一篇博客 ...

  10. JS form表单图片上传

    // 点击file 类型的input 触发的方法 function changesProvider(){ // fileProvider -> input中的name属性值 var f = do ...