每个使用关系型数据库的程序都可能遇到数据死锁或不可用的情况,而这些情况需要在代码中编程来解决;本文主要介绍与数据库事务死锁等情况相关的重试逻辑概念,此外,还会探讨如何避免死锁等问题,文章以DB2(版本9)与为例进行讲解。
什么是数据库锁定与死锁
锁定(Locking)发生在当一个事务获得对某一资源的“锁”时,这时,其他的事务就不能更改这个资源了,这种机制的存在是为了保证数据一致性;在设计与数据库交互的程序时,必须处理锁与资源不可用的情况。锁定是个比较复杂的概念,仔细说起来可能又需要一大篇,所以在本文中,只把锁定看作是一个临时事件,这意味着如果一个资源被锁定,它总会在以后某个时间被释放。而死锁发生在当多个进程访问同一数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都无法继续下去。
如何避免锁
我们可利用事务型数据库中的隔离级别机制来避免锁的创建,正确地使用隔离级别可使程序处理更多的并发事件(如允许多个用户访问数据),还能预防像丢失修改(LostUpdate)、读“脏”数据(DirtyRead)、不可重复读(NonrepeatableRead)及“虚”(Phantom)等问题。
隔离级别问题现象
丢失修改读“脏”数据不可重复读“虚”
可重复读取NoNoNoNo
读取稳定性NoNoNoYes
光标稳定性NoNoYesYes
未提交的读NoYesYesYes
表1:DB2的隔离级别与其对应的问题现象
在只读模式中,就可以防止锁定发生,而不用那些未提交只读隔离级别的含糊语句。沙河电脑培训发现一条SQL语句当使用了下列命令之一时,就应该考虑只读模式了
1 使用终端或命令提示符登录到MySQL,输入命令:mysql -h xxxxxxxxxx -P 3306 -u username -p
解释:xxxxxxxxxx是数据库IP地址,username是数据库用户名,输入命令后,会让你输入username对应的密码,就可以登录了
2 如何查看MySQL数据库的死锁信息
在MySQL客户端下输入命令:
show engine innodb status \G;
3 如何定位MySQL数据库的死锁信息
在打印出来的信息中找到“LATEST DETECTED DEADLOCK”一节内容,看图中红线
4 如何分析日志,定位死锁原因
看3里面的图,紫色划线部分
分析:
事务1,等待
RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj``score_user`,这个位置的X锁
事务2,持有
RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj``score_user`这个地方的S锁
事务2,等待这个地方的X锁
理论上这个事务2是可以提交的不会,死锁,但是这个事务日志只打印最后一部分死锁,信息,这里面隐含的条件是,事务1也持有
RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj``score_user`这个地方的S锁,这样,事务2不能加X锁,同时事务1也不能加X锁,产生死锁。
可以用sp_who'active'看一下午blk字段是否为0,如是其它数x,说明这个数可能就是锁,再用sp_who数x看一下它下面的blk是否有数,这样查下去,如果它下面没有数并且是查询状态或是等待状态等(除更新及插入状态)都可以用kill数x
execsp_lock快捷键C_2
execsp_whoactiveexecsp_who快捷键C_1
用Profiler里面的Locks->Deadlockgraph监控看看,如果看到了死锁图,就可以比较形象地展现死锁发生的过程,还可以看到锁的具体类型和过程里面的语句,对你诊断会有帮助。
Declare@LockTabtable(spidint,dbidint,ObjIdint,IndIdint,Typevarchar(50),Resourcevarchar(50),Modevarchar(50),Statusvarchar(50))
insertinto@LockTabexecsp_lock
Declare@ActiveTabtable(spidint,ecidint,statusvarchar(50),loginnamevarchar(50),hostnamevarchar(50),blkint,dbnamevarchar(50),cmdvarchar(50),request_idint)
insertinto@ActiveTabexecsp_whoactive
selectfrom@LockTablt
leftjoin@ActiveTabatonltspid=atspid
死锁检测
use master
Select from sysprocesses where blocked<>0
--找到SPID
exec sp_lock
--根据SPID找到OBJID
select object_name(85575343)
--根据OBJID找到表名
sqlserver的数据库文件是什么?以 MDF结尾的是数据库文件,以 LDF结尾的是日志文件 ;
在企业管理器中选择您的要导入数据的数据库,然后点击右键,选择所有任务-附加数据库-选择MDF文件,就可以了 ;
对于数据库的还原,最好的备份数据库后,再还原数据库。可以使用定期备份;
以上就是关于在Java程序中处理数据库超时与死锁全部的内容,包括:在Java程序中处理数据库超时与死锁、如何查看MySQL数据库的死锁信息、数据库死锁怎么处理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)