jdon 解惑授道,企业信息化解决之道
 

热点Tag: AOP cache DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Spring Struts

Jdon框架演示

JiveJdon3.0
源码下载

GoF设计模式

在线教程

社区精彩讨论












对于JBoss中容器管理的事务的疑惑

作者:mk 发表时间:2004年08月21日 17:58 回复此消息回复

原贴网址: http://www.jdon.com/jivejdon/thread/16072.html

我在SessionBean中写了一方法,该方法实现了对于同一个数据源,两步数据库的操作,都是直接调用的SQL语句。第一个SQL语句负责对一个已经存在的表进行插入记录的操作,它下面紧接的SQL对一个不存在的表做更新操作。SessionBean是容器管理的事务,并且该SessionBean中所有方法都是Required。本以为捕获到SQLException后(表或视图不存在),EJB Container会对事务做回滚操作。可实际上,EJB Container并没有这么做,我查了下数据库,发现记录已经插入进去了!

我后来把由容器管理的事务改为Bean管理的事务,于是在代码里加了
UserTransaction ut = null;
try {
ut = sessionContext.getUserTransaction();
ut.begin();
....
ut.commit();

}catch(SQLException es) {
es.printStackTrace();
try{
ut.rollback();
}catch(SystemException se) {

}
}
.....

用这样Bean管理的事务的时候,就没有问题,事务可以回滚,不会有记录被插入。

更有意思的是,我还是用容器管理的事务类型,我尝试在SQLException的catch中抛出更底层一点的异常 throw new RuntimeException();事务居然能正常回滚!

这个问题困绕了我两天,不知大家可否遇到,有兴趣的话试试,期盼各位的结果!
开发环境JBoss3.0.8 + JBuilder9.0 + JBossOpenTool(本人试过JBoss3.2.3,JBoss3.2.5结果都一样)

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月21日 19:06 回复
banq 发表文章: 8914/ 注册时间: 2002年08月03日 17:08
看你使用什么数据库,oracle必需使用oracle-xa-ds.xml配置数据源。

我曾经亲自动手在MySQl 4.0上试验OK。

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月21日 19:57 回复
daquan198163 发表文章: 143/ 注册时间: 2003年08月19日 10:56
提倡用容器管理的事务。
但是你在捕获SQL异常后,应该写一句:
sessionContext.setRollBackOnly(),
因为容器只有在捕获EJBException时才会回滚。

见《EJB设计模式》相关章节

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月21日 20:07 回复
mk 发表文章: 12/ 注册时间: 2004年08月21日 17:32
如果是Oracle的话一定要用Oracle-xa-ds.xml吗?不是吧,那为什么用Bean管理的事务就可以呢?难道用普通的Oracle-ds.xml就不能回滚了?

楼上那位仁兄,能不能告诉我那句话在《EJB设计模式》第多少页,先3Q了!

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月21日 20:32 回复
mk 发表文章: 12/ 注册时间: 2004年08月21日 17:32
谢谢楼上的那位兄弟,我在《EJB设计模式》里找到了。(第228页)

它上面说的application exceptions和developer written exceptions应该不包括RuntimeException,所以在抛那个异常的时候能正常回滚。

像它这样做,自由度就提高了些,不是所有的异常都进行回滚。这点确实很重要啊,否则真的出现了数据的不一致性就麻烦了!

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月21日 21:06 回复
daquan198163 发表文章: 143/ 注册时间: 2003年08月19日 10:56
你看的是那本翻译的吗,在166页,一共才205页呀,哈哈

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月22日 12:55 回复
mk 发表文章: 12/ 注册时间: 2004年08月21日 17:32
我这是英文版的啊! 一908KB的PDF文档啊!

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月22日 12:57 回复
mk 发表文章: 12/ 注册时间: 2004年08月21日 17:32
ejbdesignpatterns.pdf

我忘了在哪下的了,一共289页。

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月25日 11:32 回复
daquan198163 发表文章: 143/ 注册时间: 2003年08月19日 10:56
12个最重要的J2EE最佳实践

…………

8. 使用容器管理的事务。

学习一下 J2EE 中的两阶段提交事务,并且使用这种方式,而不是开放您自己的事务管理。容器在事务优化方面几乎总是比较好的。

使用容器管理的事务(CMT)提供了两个关键的优势(如果没有容器支持这几乎是不可能的):可组合的工作单元和健壮的事务行为。

如果您的应用程序代码显式地使用了开始和结束事务(也许使用 javax.jts.UserTransaction 或者甚至是本地资源事务),而将来的要求需要组合模块(也许会是代码重构的一部分),这种情况下往往需要改变事务代码。例如,如果模块 A 开始了一个数据库事务,更新数据库,随后提交事务,并且有模块 B 做出同样的处理,请考虑一下当您在模块 C 中尝试使用上述两个模块,会出现什么情况呢?现在,模块 C 正在执行一个逻辑动作,而这个动作实际上将调用两个独立的事务。如果模块 B 在执行中失败了,而模块 A 的事务仍然能被提交。这是我们所不希望出现的行为。如果,相反地,模块 A 和模块 B 都使用 CMT 的话,模块 C 也可以开始一个 CMT(通常通过配置描述符),并且在模块 A 和模块 B 中的事务将是同一个事务的隐含部分,这样就不再需要复杂的重写代码的工作了。

如果您的应用程序在同一个操作中需要访问多种资源,您就要使用两阶段提交事务。例如,如果从 JMS 队列中删除一个消息,并且随后更新基于这条消息的纪录,这时,要保证这两个操作都会执行或都不会执行就变得尤为重要。如果一条消息已经从队列中被删除,而系统没有更新与此消息相关的数据库中的纪录,那么这种系统是不稳定的。一些严重的客户及商业纠纷源自不一致的状态。

我们时常看到一些客户应用程序试图实现他们自己的解决方案。也许会通过应用程序的代码在数据库更新失败的时候 “撤销”对队列的操作。我们不提倡这样做。这种实现要比您最初的想象要复杂得多,并且还有许多其他的情况(想象一下如果应用程序在执行此操作的过程中突然崩溃的情况)。作为替代的方式,应该使用两阶段提交事务。如果您使用 CMT,并且在一个单一的 CMT 中访问两阶段提交的资源(例如 JMS 和大多数数据库),WebSphere 将会处理所有的复杂工作。它将确保整个事务被执行或者都不被执行,包括系统崩溃、数据库崩溃或其他的情况。其实现在事务日志中保存着事务状态。当应用程序访问多种资源的时候,我们怎么强调使用 CMT 事务的必要性都不为过。

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月25日 23:28 回复
banq 发表文章: 8914/ 注册时间: 2002年08月03日 17:08
>sessionContext.setRollBackOnly(),

EJB方法中不需要写任何语句,只要有Exception抛出,就可以事务回滚。

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月26日 09:12 回复
daquan198163 发表文章: 143/ 注册时间: 2003年08月19日 10:56
>只要有Exception抛出,就可以事务回滚

banq ,好像跟弗洛伊德说得不太一样呀

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月30日 09:32 回复
holykeeper 发表文章: 25/ 注册时间: 2004年06月23日 17:23
应该是抛出系统级的异常才可以回滚,包javax.ejb的异常类中,除了NoSuchEntityException和EJBException属于系统级异常外,其他的异常全部是应用级异常。
照搂主的说法还有
RuntimeException也属于系统级的。

但一个异常究竟属于哪个级别,从哪里查阿?

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月30日 09:51 回复
daquan198163 发表文章: 143/ 注册时间: 2003年08月19日 10:56
确切的说是运行时异常,即RuntimeException及其子类,也就是那些即使抛出也不需要声明throws 的

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年08月30日 09:56 回复
wwlhp@jdon 发表文章: 67/ 注册时间: 2003年04月25日 12:07
总结一下,
1> 如果bean抛出RuntimeException,容器会自动回滚事务,并且在外面包装一个RemoteException抛出。
2> 如果bean抛出其他的异常,容器不会做任何处理。

Re: 对于JBoss中容器管理的事务的疑惑 发表: 2004年09月07日 11:02 回复
zdbj2ee 发表文章: 44/ 注册时间: 2003年08月29日 09:14
JBOSS这个东西,EJB容器管理事务有问题,我在jboss和oracle8.17使用XADataSource也就是oracle-xa-ds.xml配置,在EJB中得到数据库连接正常
但在容器提交tx事务时,出错,说什么xid错误.我把这段代码放在weblogic中一点问题都没有。JBOSS让人无法理解。我现在已改用weblogic了,没办法。

这个主题共有 24 回复 / 2 页 [ 1 2 下一页 ]
 
上一篇: 关于jboss3.0.7中mdb运用中的.. 下一篇: ★★★★★EJB之client jar ..
 
查询本论坛 最热门帖子
快速发表回复:
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
 
联系我们 | 关于我们 | RSS订阅 | 广告联系 | 网站地图 | 设为首页
Copyright (C) 2002-2007 Jdon.com, All Rights Reserved 版权所有 上海解道计算机技术有限公司
沪ICP备05018152号 如有意见请与我们联系 Powered by JdonFramework