Oracle死锁产生的原因和解决办法
如果有两个会话,每个会话都持有另一个会话想要的资源,此时就会发生死锁。
用下面实验来说明死锁的产生原因和解决办法。
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死锁产生的原因和解决办法的更多相关文章
- mysql数据库死锁的产生原因及解决办法
这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下 数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同 ...
- Oracle常见死锁发生的原因以及解决方法
Oracle常见死锁发生的原因以及解决办法 一,删除和更新之间引起的死锁 造成死锁的原因就是多个线程或进程对同一个资源的争抢或相互依赖.这里列举一个对同一个资源的争抢造成死锁的实例. Oracle 1 ...
- ORA-00907: 缺失右括号,原因及解决办法整理
ORA-00907: 缺失右括号,原因及解决办法整理 1 union all中order by 导致缺失右括号 在有union all的子查询中使用了order by,会导致缺失右括号的错误,事实上在 ...
- jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法
jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法 在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...
- java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver 错误的解决办法
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver 错误的解决办法 (2011-05-05 16:08:05) 转载▼ ...
- 各种编码问题产生原因以及解决办法---------响应编码,请求编码,URL编码
响应编码 产生原因以及解决办法: 示例: package cn.yzu; import java.io.IOException; import javax.servlet.ServletExcept ...
- .Net内存泄露原因及解决办法
.Net内存泄露原因及解决办法 1. 什么是.Net内存泄露 (1).NET 应用程序中的内存 您大概已经知道,.NET 应用程序中要使用多种类型的内存,包括:堆栈.非托管堆和托管堆.这里我们需 ...
- HttpClient的CircularRedirectException异常原因及解决办法
HttpClient的CircularRedirectException异常原因及解决办法 这两天在使用我自己爬虫抓取网页的时候总是出现 org.apache.http.client.ClientPr ...
- php_curl.dll libssh2.dll 始终无法加载的原因 及解决办法
在StackOverflow得到最终原因及解决办法 http://stackoverflow.com/questions/16424117/php-unable-to-load-php-curl-dl ...
随机推荐
- .net中大数据的处理
前提:sqlserver数据库 问题:需要从数据量达千万级或是更大的数据库中找出一条需要的数据. 1,先分析大数据的结构,以及数据的流向.以及此过程中那些地方会有瓶颈. 2,针对瓶颈制定方案: 1.1 ...
- 转: MVC设计思想简介
模型-视图-控制器(MVC)是80年代Smalltalk-80出现的 一种软件设计模式,现在已经被广泛的使用. 1.模型(Model) 模型是应用程序的主体部分.模型表示业务数据,或者业务逻辑. 2. ...
- bzoj 3130: [Sdoi2013]费用流
#include<cstdio> #include<iostream> #define M 10000 #define inf 0x7fffffff #include<c ...
- Leetcode 58 Length of Last Word 难度:0
https://leetcode.com/problems/length-of-last-word/ int lengthOfLastWord(char* s) { int ans = 0; int ...
- Client默认用户及登录密码(转)
Client默认用户及登录密码 SAP系统(如ERP.CRM等)安装完成,初始化状态下有若干个客户端(Client).如果是生产系统,一般只有000.001.066等三个Client:如果是IDES系 ...
- BestCoder Round #43
T1:pog loves szh I(hdu 5264) 题目大意: 给出把AB两个字符串交叉拼起来的结果,求出原串. 题解: 不解释..直接每次+2输出. T2:pog loves szh II(h ...
- SunSonic 3.0 ORM开源框架的学习
SubSonic 3.0简介 接触到SubSonic3.0 ORM框架是看了AllEmpty大神的从零开始编写自己的C#框架(链接在此)系列的随笔接触到的,本文章学习内容源于AllEmpty大神. S ...
- leetcode N-Queens/N-Queens II, backtracking, hdu 2553 count N-Queens, dfs 分类: leetcode hdoj 2015-07-09 02:07 102人阅读 评论(0) 收藏
for the backtracking part, thanks to the video of stanford cs106b lecture 10 by Julie Zelenski for t ...
- 我是一只IT小小鸟
不知不觉中走过了高三的时光,最后也没抓住时间的尾巴,不得不承认自己已经到了大一下学期了.接触了大学生职业生涯规划这门课程,一开始认为学习了这门课程以后就会对自己的未来有一个规划,渐渐的去意识到软件工程 ...
- sql 跨域
1. 开通分布式查询权限 reconfigure reconfigure 2. 查询 ',NETACS.dbo.tb_car) a select * from opendatasource('SQLO ...