为什么CMT在EJB方法退出时提交,当事务属性为“必需”时? [英] Why does CMT commit on exit of EJB method, when transaction attribute is "Required"?

查看:109
本文介绍了为什么CMT在EJB方法退出时提交,当事务属性为“必需”时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在发现,我已经存在的事务正在EJB标记的任何方法中得到承诺 @ ejb.transaction type =Required 。这可以吗?



我的期望是,一个EJB需要一个事务意味着:如果有一个已经存在的话,那么在完成之后会礼貌地将其取消提交,以便调用begin()的人可以在调用 commit() rollback()之前继续使用它进行进一步的操作。 [当然,如果没有事务首先,EJB方法将调用 begin() commit() / rollback()。]



我的期望是错误的,还是我要找的配置错误?



添加我在EJB内使用Hibernate 3可能是相关的。在调用EJB方法之前,我正在获取一个UserTransaction。 EJB生成的包装器在退出时调用 ServerTransaction.commit(),Hibernate挂接并使用机会关闭其会话。我得到的错误是Hibernate懒惰加载异常,因为当我尝试访问Hibernate持久对象的getter时,会话关闭。所以技术上,我不是100%确定是否 ServerTransaction.commit()我观察到必须提交 UserTransaction I开始(可能 ServerTransaction.commit()并不总是实际上遵循一个真正的提交?),但如果没有 - 那么在什么基础上是Hibernate关闭会话?



更新: 我相信我上面的假设是正确的,但我的观察结果有点偏离。请参阅下面的自我提供的答案。

解决方案

仔细检查显示与上述不同的答案。我实际看到的是,我启动的UserTransaction一直保持打开状态,但是CMT在EJB方法的条目中创建了一个新的事务,尽管有必需属性。



我相信这是因为我违反规则而发生的。 :)在使用CMT时,您不应访问UserTransaction API。 CMT高兴地忽略了我的UserTransaction并开始自己的,已经把它作为所有事务边界的仲裁者。自从它开始交易以来,它也承诺了这一点,当然还有我的UserTransaction没有改变。



似乎对我来说很脆弱,也许是一个天真的意见,随着我读了他们的规则。我不知道为什么CMT选择不会在较高级别开始使用UserTransactions玩好。也许强制开发人员做正确的J2EE事情,并创建另一个会话bean层来处理更广泛的事务环境。这将是有效的,因为CMT将管理外部交易,因此招募任何内部交易将是正常的,我相信在这种情况下,内部EJB不会执行伞事务; CMT将等待外部事务完成,然后提交整个事情。实际上它将不得不实现。



我没有心情在这个已经EJB blo肿的应用程序中创建更多的会话EJB,但它可能是唯一的解决方案在一大堆地方,我不想触摸CMT。


I am consistently finding that my already-existing transaction is getting committed inside any method of an EJB marked @ejb.transaction type="Required". Can this be correct?

My expectation is, an EJB "requiring" a transaction means: if there's one already there, it will politely leave it uncommitted when done so that whoever invoked begin() can continue to use it for further operations before invoking commit() or rollback(). [Of course, if there was no transaction in the first place, then the EJB method would invoke both begin() and commit()/rollback().]

Is my expectation wrong, or should I be looking for a configuration bug?

It might be relevant to add that I'm using Hibernate 3 inside the EJB. I'm obtaining a UserTransaction before calling the EJB method. The EJB generated wrapper invokes ServerTransaction.commit() on exit, which Hibernate hooks into and uses the opportunity to close its Session. The error I'm getting is a Hibernate lazy loading exception, because the session is closed when I try to access getters on a Hibernate-persisted object. So technically, I'm not 100% sure whether the ServerTransaction.commit() I observed necessarily committed the UserTransaction I started (maybe ServerTransaction.commit() doesn't always actually follow through with a "real" commit?), but if it did not -- then on what basis is Hibernate closing the Session?

Update: I believe my assumptions above were correct, but my observations were a bit off. See below for my self-supplied Answer.

解决方案

Closer inspection reveals a different answer than suggested above. What I'm actually seeing is that the UserTransaction I started has remained open, but CMT created a new transaction on entry to the EJB method, despite the "Required" attribute.

I believe this is happening because I broke the rules. :) You aren't supposed to access the UserTransaction API when using CMT. CMT happily ignored my UserTransaction and started its own, having taken its place as the arbiter of all transaction boundaries. Since it started the transaction, it committed it as well, and of course left my UserTransaction untouched.

Seems brittle and silly to me, perhaps a naive opinion, but appears consistent with the "rules" as I read them. I don't know why CMT chooses not to play nice with UserTransactions started at a higher level. Perhaps to force developers to "do the right J2EE thing" and create another session bean layer to handle the broader transaction context. This would work because CMT would be managing the outer transaction and therefore would be fine with enlisting any inner transactions, and I believe in such a case, the "umbrella" transaction would not be committed by the inner EJBs; CMT would wait until the outer transaction completes, then commit the whole thing. It would have to, actually.

I'm not in the mood to create more session EJBs in this already EJB-bloated app, but it may be the only solution short of ripping CMT out in a whole bunch of places I'd rather not touch.

这篇关于为什么CMT在EJB方法退出时提交,当事务属性为“必需”时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆