快速业务通道

对J2EE中死锁问题的研究 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-21

对J2EE中死锁问题的研究

时间:2011-01-05 bea Michael Nonemacher

大多数重要的应用程序都涉及高度并发性和多个抽象层。并发性与资源争用有关,并且是导致死锁问题增多的因素之一。多个抽象层使隔离并修复死锁环境的工作变得更加困难。

通常,当同时执行两个或两个以上的线程时,如果每个线程都占有一个资源并请求另一个资源,这时就会出现死锁情况。因为如果一个线程不能获取资源,则所有线程都不能继续执行,我们称那个特定的线程被阻塞;如果每个线程都由于同组中另一个线程所占有的资源而被阻塞,我们就称这个线程组被死锁。

在本文中,我们将讨论发生在典型的重要J2EE应用程序中的两大类死锁情况:“简单”数据库死锁和跨资源死锁。虽然我们的讨论基于J2EE平台,但也适用于其他技术平台。

数据库死锁

在数据库中,如果一个连接占用了另一个连接所需的数据库锁,则它可以阻塞另一个连接。如果两个或两个以上的连接相互阻塞,则它们都不能继续执行,这种情况称为死锁。

数据库死锁问题不易处理,这是因为涉及到的锁定通常不是显式的。通常,对数据行进行隐式更新时,需要锁定该数据行,执行更新,然后在提交或回滚封闭事务时释放锁。由于数据库平台、配置的隔离级以及查询提示的不同,获取的锁可能是细粒度或粗粒度的,它会阻塞(或不阻塞)其他对同一数据行、表或数据库的查询。

获取的锁依赖于内部生成的查询计划。当数据大小和分步随时间发生变化时,该计划也可能改变。这样在一个环境中获取一组锁的查询可以尝试在另一个环境中获取一组完全不同的锁。必要时,数据库可以随意地增加它的锁。例如,数据库可能会选择锁定整页,而不是锁定同一数据页中的10个数据行,这会阻塞对无需锁定的数据行的读写权限。

基于数据库模式,读写操作会要求遍历或更新多个索引、验证约束、执行触发器等。每个要求都会引入更多锁。此外,其他应用程序还可能正在访问同一数据库模式中的某些对象,并获取不同于您的应用程序所具有的锁。

所有这些因素综合在一起,数据库死锁几乎不可能被消除了。值得庆幸的是,数据库死锁通常是可恢复的:当数据库发现死锁时,它会强制销毁一个连接(通常是使用最少的连接),并回滚其事务。这将释放所有与已经结束的事务相关联的锁,至少允许其他连接中有一个可以获取它们正在被阻塞的锁。

由于数据库具有这种典型的死锁处理行为,所以当出现数据库死锁问题时,数据库常常只能重试整个事务。当数据库连接被销毁时,会抛出可被应用程序捕获的异常,并标识为数据库死锁情况。如果允许死锁异常传播到初始化该事务的代码层之外,则该代码层可以只启动一个新事务并重做先前所有工作。要正确使用此策略,则在事务成功提交之前,它的代码不能有其他操作。注意:要限制重试次数,否则易导致死锁的代码块会永久循环下去。

如果出现问题就重试,这种方法有点笨。但是,由于数据库可以自由地获取锁,所以几乎不可能保证两个或两个以上的线程不发生数据库死锁。此方法至少能保证在出现某些罕见的数据库死锁情况时,应用程序能正常运行。这比要求用户去重试操作要好得多。

在J2EE应用程序中,开发人员可以设置一个EJB调用以使用Bean托管事务(BMT)——开发人员启动、提交或回滚特定的事务或容器托管事务(CMT)——调用方法前启动事务,并在方法完成后提交或回滚事务。如果EJB供应商提供retry-on-deadlock参数,从而可以通过容器托管事务自动完成此操作,那当然再好不过了。如果没有这种自动功能,开发人员最终将仅为了对死锁进行重试而强制EJB调用使用Bean托管事务。

遇到死锁问题和锁定其他线程的锁的具体频率在很大程度上取决于数据库平台、硬件、数据库模式和查询。在使用基于

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号