应用重启会导致数据库锁记录,如何预防死锁

今天有个开发人员,一天之内,产生了好几次记录被锁没有释放,大致情况是这样的:

应用中有个定时:select xxx  for update,2分钟执行一次。执行过程中有commi;这个job是单线程的,照理说应该不会产生死锁。开始这个问题我也觉得挺奇怪,后来在同事的帮助下,又问了一下程立,终于明白了:

在停止应用的时个,因为是kill的,所以数据库的行锁没有被释放,在数据库本身清理这个session之前,应用再次重启,访问同样的一些记录,在访问的时候,有部分资源竞争所以导致了这个问题,我理解应该不是是死锁。

之后通过数据库把orace session kill就解决了问题。

在程序设计的时候,但是也学习到了,一定要防止多线程并发访问一些交叉的数据,极有可能产生死锁。

 

以下是程立的回答,受益匪浅。

 

公司目前应用重启是直接kill应用服务器的(如果是正常发布,会首先禁止新建session一段时间),这样完全可能出现执行中的事务被中断的情况。

应用服务器在这个时候没有机会主动回滚事务,因此是由数据库自动回滚事务的。这一过程应该是非常快的。

如果是用jboss自己的shutdown命令或者ctrl+C,会逐一停止各个服务、undeploy应用,这个过程中可能会等待正在执行的任务完成,这时事务会提交掉;但总的说来这个过程不一定是可靠的。

总的说来,必须认为应用重启时处于执行中的事务的状态是无法事先确定的,提交与回滚都有可能。

在设计应用时,无论提交还是回滚都是可接受的。回滚的结果可能更好一些,因为在与用户进行交互时可以避免在用户在无法看到业务结果时就完成了业务,从而引起体验上的问题。

你可能感兴趣的:(多线程,数据库,应用服务器,jboss,session,kill)