oracle数据表造成死锁,解决方法
一、死锁的表现
1、错误信息是:事务(进程 ID)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
2、错误信息是:事务(进程 ID )与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
二、死锁的原因
1、由于多用户、多任务的并发性和事务的完整性要求,当多个事务处理对多个资源同时访问时,若双方已锁定一部分资源但也都需要对方已锁定的资源时,无法在有限的时间内完全获得所需的资源,就会处于无限的等待状态,从而造成其对资源需求的死锁。
2、数据库本身加锁机制的实现方法不同,各数据库系统也会产生其特殊的死锁情况。如在Sybase SQL Server 11 中,最小锁为 2K
一页的加锁方法,而非行级锁。如果某张表的记录数少且记录的长度较短(即记录密度高,如应用系统中的系统配置表或系统参数表就属于此类表),被访问的频率高,就容易在该页上产生死锁。
表现一:
一个用户 A 访问表 A(锁住了表 A),然后又访问表 B。另一个用户 B 访问表 B(锁住了表 B),
然后企图访问表 A。这时用户 A 由于用户 B 已经锁住表 B,它必须等待用户 B 释放表 B,
才能继续,同样用户 B 要等用户 A 释放表 A 才能继续操作,这样就造成了死锁。
解决方法:
这种死锁是由于程序的 BUG 产生的,需调整程序对数据库层的实现逻辑。仔细分析程序的逻辑:
(1)尽量避免同时锁定两个资源。
(2)必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。
表现二:
用户 A 读一条纪录,然后修改该条纪录,同时用户 B 也修改该条纪录。这里用户 A 的事务里锁的性质由共享锁企图上升到独占锁 (for update),而用户 B 里的独占锁由于 A 有共享锁存在所以必须等 A 释放掉共享锁,而 A 由于 B 的独占锁而无法上升的独占锁也就不可能释
放共享锁,于是出现了死锁。这种死锁比较隐蔽,但其实在稍大点的项目中经常发生。
解决方法:
让用户 A 的事务(即先读后写类型的操作),在 select 时就是用 update lock。
语法如下:select * from table1 with(updlock) where ….
三、常见死锁情况及解决方法
1、不同的存储过程、触发器、动态 SQL 语句段按照不同的顺序同时访问多张表。
在系统实现时应规定所有存储过程、触发器、动态 SQL 语句段中,对多张表的操作总是使用同一顺序。如:有两个存储过程 procedure1、procedure2,都需要访问三张表 table1、table2
和 table3,如果 procedure1 按照 table1、table2 和 table3 的顺序进行访问,那么,procedure2也应该按照以上顺序访问这 3 张表。
2、在交换期间添加记录频繁的表,但在该表上使用了非群集索引(non-clustered)。
对在交换期间添加记录频繁的表,使用群集索引(clustered),以减少多个用户添加记录到该表的最后一页上,在表尾产生热点,造成死锁。这类表多为往来账的流水表,其特点是在交换期间需要在表尾追加大量的记录,并且对已添加的记录不做或较少做删除操作。
3、表中的记录少,且单条记录较短,被访问的频率较高。
对单张表中记录数不太多,且在交换期间 select 或 update 较频繁的表可使用设置每页最大行的办法,减少数据在表中存放的密度,模拟行级锁,减少在该表上死锁情况的发生。这类表多为信息繁杂且记录条数少的表。
如:系统配置表或系统参数表。在定义该表时添加如下语句: with max_rows_per_page=1
4、整张表被访问的频率高(如代码对照表的查询等)。
在存储过程、触发器、动态 SQL 语句段中,若对某些整张表 select 操作较频繁,则可能在
该表上与其他访问该表的用户产生死锁。对于检查账号是否存在,但被检查的字段在检查期间不会被更新等非关键语句,可以采用在 select 命令中使用 at isolation read uncommitted 子句的方法解决。该方法实际上降低了 select 语句对整张表的锁级别,提高了其他用户对该表
操作的并发性。在系统高负荷运行时,该方法的效果尤为显著。
例如: select*from titles at isolation read uncommitted
5、对流水号一类的顺序数生成器字段,可以先执行 update 流水号字段+1,然后再执行 select
获取流水号的方法进行操作。
备注:
NOLOCK(不加锁):此选项被选中时,SQL Server 在读取或修改数据时不加任何锁。在这种情况下,用户有可能读取到未完成事务(Uncommitted Transaction)或回滚(Roll Back)中数据,即所谓的“脏数据”。
UPDLOCK(修改锁):此选项被选中时,SQL Server 在读取数据时使用修改锁来代替共享锁,并将此锁保持至整个事务或命令结束。使用此选项能够保证多个进程能同时读取数据但只有该进程能修改数据。
发生死锁后可通过如下存储过程查看详细的死锁信息,如下所示:
Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0
Connected as quik
SQL> select xidusn, object_id, session_id, locked_mode from v$locked_object; --查死锁的对象,获取其SESSION_ID
XIDUSN OBJECT_ID SESSION_ID LOCKED_MODE
---------- ---------- ---------- -----------
10 30724 29 3
10 30649 29 3
SQL> select username,sid,serial# from v$session where sid=29; --根据上步获取到的sid查看其serial#号
USERNAME SID SERIAL#
------------------------------ ---------- ----------
QUIK 29 57107
SQL> alter system kill session '29,57107'; --删除进程,如已经删除过,则会报ora-00031的错误;否则oracle会将该session标记为killed状态,等待一段时间看能否会自动消失,如长时间消失不掉,则需要做后续步骤
alter system kill session '29,57107'
ORA-00031: session marked for kill
SQL> select pro.spid from v$session ses,v$process pro where ses.sid=29 and ses.paddr=pro.addr; --查看spid号,以便在操作系统中根据该进程号删除进程
SPID
------------
2273286
通过以上的方法,一步一步循序渐进,就能解决掉数据库死锁的现象,让你的数据库重归正常!
oracle数据表造成死锁,解决方法相关推荐
- oracle锁表原因,解决方法
1.oracle数据库表在操作insert update .delete 时忘记提交事务或者回滚,就会发生锁表 2.锁表的原理是 数据库使用独占式封锁机制,当执行上面的语句时,对表进行锁住,直到发 ...
- oracle主从关系表查询,Oracle 主从表联合查询解决方法
Oracle 主从表联合查询 表A id type name 1 E AA 2 F 表B id Aid name 1 2 BB 2 2 ...
- oracle导入表无反应,EZDML无法导入oracle数据表的解决方法
EZDML无法导入oracle数据表的解决方法 EZDML无法导入oracle数据表的解决方法 1.配置好oracle连接,进行导入数据表时报错:sql*net not properly instal ...
- Oracle中新建数据表的两种方法
首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1 ...
- php下载文件压缩包已经损坏或未知格式,这个压缩文件格式未知或者数据已经被损坏解决方法...
"这个压缩文件格式未知或者数据已经被损坏"解决方法 1.如果是从网上下载的压缩文件,很有可能是网站提供的本身就是损坏的压缩文件.如果重新下载之后仍然是损坏的,可以从其他网站下载. ...
- mysql 闪回_MySQL数据误删除的快速解决方法(MySQL闪回工具)
概述 Binlog2sql是一个Python开发开源的MySQL Binlog解析工具,能够将Binlog解析为原始的SQL,也支持将Binlog解析为回滚的SQL,去除主键的INSERT SQL,是 ...
- mysql5.7更改数据库存储位置_mysql 5.7更改数据库的数据存储位置的解决方法
随着mysql数据库存储的数据逐渐变大,已经将原来的存储数据的空间占满了,导致mysql已经链接不上了.因此,必须要给存放的数据换个地方了.下面是操作过程中的一些步骤.记下来,以后日后查看. 1.修改 ...
- Oracle数据表导入导出_数据迁移用
0.背景:突然接到居家办公的通知,工作用数据全部在内网,需要全部拷出带走,最大的单个表3.7G左右.根据往常经验将Oracle库中表导出为xlsx(方便与同事沟通使用),发现效率太低,且受制于数据量太 ...
- Mysql删除数据特别慢及解决方法
Mysql删除数据特别慢及解决方法 1.前言 笔者的mysql表数据量大概是1亿条,然后直接删除某一批次数据的时候,删除操作极其缓慢,执行了很久之后都不能删除成功.我就终止这个操作了. 2.问题 但是 ...
最新文章
- 315MHz 高频射频发射模块
- 按作用域分的话 php的变量可分为,mysql全局变量表
- C++刷称号——2707: 素数与要素
- 远程连接server问题
- Android-完全退出当前应用程序-新公司学习到的细节
- php怎么取json数组元素个数,json,数组_取出json数据中的某一项组成一个数组?,json,数组,php - phpStudy...
- SPOJ 1811 Longest Common Substring
- 网络空间信息安全-密码学-信息密码技术基础
- 阿里云 CentOS 7.4 下部署基于 Node.js 的微信小程序商城
- mysql间隙锁 打开_MySQL数据库间隙锁
- Refresh PDB
- 模式识别和计算机科学与技术,模式识别与智能系统
- 3.2收缩-扩张喷管实例
- 使用Web浏览器访问远程ssh终端
- 开手游要选用怎么样的服务器
- iOS - 添加代码片段(Code Snippets)
- 什么是算法?算法的5个特性
- 【汉字编码几个字节】
- 简单工厂设计模式与工厂设计模式
- Ultimaker Cura 4.9.X 开发教程 (零)