Oracle死锁问题分析解决
2014-03-12 21:10
381 查看
Oracle死锁问题分析解决
死锁发生的情况一般是资源存在环形依赖。Oracle上的死锁一般出现于“行级锁”的环形依赖情况下:
有记录A、B,事务T1、T2,现在T1、T2并发执行update(或delete)A+B
事务T1操作的顺序为A-B,正常情况下会先后锁住A和B
事务T2操作的顺序为B-A,正常情况下会先后锁住B和A
T1、T2并发执行,T1锁住A 同时 T2锁住B;
T1操作完A想要锁住B,但B已被T2锁住,T1等待中;T2操作完B想要锁住A,但A已被T1锁住,T2等待中;
由于T1、T2都在等待又都不释放,因此造成死锁。
当死锁越来越多的时候,数据库连接被耗尽,不再能接受新的连接;数据库服务器的CPU和内存也可能会不够用了……程序猿就悲剧了。
解决办法:
在事务开始时或开始前先对操作数据按统一规则排序。
例如:按A-B顺序排序,使得T1、T2操作的顺序都为A-B,假设T1、T2并发执行时T1锁住了A;则T2只能等待A的锁了,B就没有机会被T2锁住了;这样T1就可以顺利锁住B,并顺利执行;当T1执行完成,释放A、B,T2就可以继续执行了。
从线上死锁的情况来看,主要发生在以下两种场景:
在同一个事务中无序的update或delete多条记录,事务并发执行可能会有死锁。
没有事务,但执行单条update或delete SQL时,如果update或delete所影响的记录数大于1,也有可能出现死锁。
对于第1种场景可以使用前述的解决办法处理,即先排序后执行;
对于第2种场景的解决办法如下:
先用select查询出需要操作的记录主键,按主键排序,再通过主键一条一条迭代执行。
不过将一条语句变成多条语句执行会破坏原有的事务(JDBC默认事务:一条SQL语句即一个事务),无法保证操作的原子性了,这就需要将这些操作放入一个事务中。或者可以使用 in 语句将其改造成一条SQL,例如:update ... where id in ( 1,2,3,4... ) ...,这样效率会比多条SQL语句高一些,而且 in 是可以命中索引的。
相关文章推荐
- Oracle EBS R12.0.6 - 禁用Command Line JVM System Properties设置的全局Low-level logging
- 【ORACLE】flash recovery area(闪回恢复区)管理
- Oracle EBS R12.0.6 - XXX is not a valid responsibility for the current user. Please contact your Sys
- 【ORACLE RAC】修改归档位置: FRA和其他位置
- Python初学之连接Oracle数据库
- java 执行多条oracle
- Oracle与Mysql主键、索引及分页的区别小结
- oracle数据库元数据SQL查询
- 64位windows 8.1安装Oracle11g和Navicat Premium连接Oracle
- SQL Server与Oracle对表添加列的不同点
- SQL Server 和Oracle 数据类型对应
- ORACLE中decode中不能使用通配符问题
- Oracle 11g RAC ASM 错误之(1)
- Oracle
- Linux下Oracle 10.2.0.1升级到10.2.0.4总结
- 浅谈mysql,sql server,oracle之差异
- Oracle RAC 深度解析之(2)
- oracle本月、上月、去年同月第一天最后一天
- oracle中bulk collect into用法
- Oracle数据库的导入导出