在Java程序中处理数据库超时与死锁

在Java程序中处理数据库超时与死锁,第1张

每个使用关系型数据库的程序都可能遇到数据死锁或不可用的情况,而这些情况需要在代码中编程来解决;本文主要介绍与数据库事务死锁等情况相关的重试逻辑概念,此外,还会探讨如何避免死锁等问题,文章以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数据库的死锁信息、数据库死锁怎么处理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9843524.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存