您的位置:首页 > 其它

bboss persistent事务框架针对BS TX泄露问题的处理

2008-12-18 11:49 225 查看

前言

bboss persistent中事务管理机制依赖于本地线程java.lang.ThreadLocal类对象,ThreadLocal对象又依赖于当前程序执行的线程。在一般情况下,只要事务被正确的管理(开始,提交/回滚),整个事务管理机制是安全的,可靠的。
非线程池应用系统中,如果事务没有被正确的管理(开始后没有正确提交或没有正确回滚),会造成事务中使用的资源(数据库链接)被泄漏,最终会导致链接池中的链接全部被泄漏,使得系统无法继续正常运行。
基于线程池的应用系统与非线程池应用系统情况类似,如果事务没有被正确的管理(开始后没有正确提交或没有正确回滚),会造成事务中使用的资源(数据库链接)被泄漏,最终会导致链接池中的链接全部被泄漏,使得系统无法继续正常运行。基于线程池的应用系统中还会出现另外一个比较严重的问题。当该线程重新被分配服务于其他应用程序时,遗留在线程中的事务(没有提交或回滚的事务)会影响会造成应用程序中的事务处理紊乱。
服务于BS应用系统应用服务器就是一种典型的基于线程池的系统,针对上述的问题,事务框架给出了一种非常合理的处理方法。


问题描述

BS业务程序使用事务框架时,如果开启事务后,如果没有确保事务最终被提交或回滚,就会造成这个事务驻留在应用服务器(weblogic)的线程池中当前被请求的线程中,当有驻留了遗留事务的线程被服务于其他请求时,遗留的事务将继续被相关业务程序使用,就会造成不可预知的错误。

原因分析

BS前台业务处理时,一次业务处理的数据库事务的最大有效范围和应用服务器产生的request对象的生命周期一致,也就是说一个数据库事务不能跨服务器的request存在,当请求结束时,如果还存在没有结束事务则必须强制结束该事务。
另外,在客服端请求到来时应用服务器会从服务器的请求服务线程池中获取一个空闲的处理线程来处理该请求,这个处理线程会关联一个本地线程,用来存放与该线程相关的独占资源,存放于这个本地线程中的资源不会被其他处理线程使用,也就是说这些资源是线程安全的。
由于服务器的请求服务线程池的中的服务线程会被重用于多个客服端请求的,服务完一个请求后,会继续用来处理其他的客服端请求。这样一旦服务线程中出现了上次服务请求时遗留下来的数据库事务对象时,则会违反“一次业务处理的数据库事务的最大有效范围和应用服务器产生的request对象的生命周期一致”的规则,造成系统处理不正常的情况。

解决方法

1. 修改有问题的业务程序,确保事务被正确的回滚和提交,杜绝事务对象被泄漏的可能性。
2. 修改事务框架,提供框架级别的事务回收机制,避免在业务程序没有正确管理事务的情况下造成数据库链接资源泄漏,避免影响后续的业务处理。
修改的方法如下:
2.1 在web应用的web.xml部署描述文件中添加管理客服端request对象生命周期的监听器
2.2 在request监听器的请求销毁处理方法中检测服务于当前被销毁的request的线程的本地线程中是否有遗留的事务处理对象,如果有则销毁该对象,这样就杜绝了事务对象被非法带入其他客服端request的可能性,有效地回收了被泄漏的数据库链接资源
2.3 由于应用服务器对所有类型url(jsp页面,html,图片,css,js等等)的请求都会创建request对象,因此request监听器只对jsp和servlet进行处理,其他类型的url将被忽略。
2.4 Web.xml中配置监听器如下:
在web应用中使用事务框架时需要在web.xml中配置如下信息,用来强制回收系统中没有正常回收的系统资源:
<listener>
<listener-class>com.frameworkset.listener.BSServletRequestListener
</listener-class>
</listener>

bboss项目下载列表 在sourceforge访问地址为:
https://sourceforge.net/project/showfiles.php?group_id=238653
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: