Java EJB3 事务回滚
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2360764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
EJB3 transaction rollback
提问by ruwan.jayaweera
I'm using CMT in EJB3 state-less session beans. Also I've created my own Exception having the annotation "@ApplicationException (rollback=true)".
我在 EJB3 无状态会话 bean 中使用 CMT。另外,我创建了自己的异常,带有注释“@ApplicationException (rollback=true)”。
Do I have to use "context.setRollbackOnly()" when I want to rollback the transaction?
Can I just rollback the transaction by throwing an exception inside public method in the bean?
If so (the answer to Q#2 is yes) do I have to throw the exception out of the method by declaring the exception in the method or will it be sufficient to just throw an exception inside the method and handle it inside the same method itself? (I don't want to propagate the exception to the next level. I just want to rollback the exception.)
当我想回滚事务时是否必须使用“context.setRollbackOnly()”?
我可以通过在 bean 的公共方法中抛出异常来回滚事务吗?
如果是这样(Q#2 的答案是肯定的),我是否必须通过在方法中声明异常来将异常抛出方法之外,还是只在方法内抛出异常并在同一方法内处理它就足够了本身?(我不想将异常传播到下一个级别。我只想回滚异常。)
Thanks in advance. ;)
提前致谢。;)
采纳答案by Steve
First of all, there is no rollback of an exception, it's a rollback of a transaction.
首先,没有异常回滚,它是事务的回滚。
- If you throw your exception with
@ApplicationException(rollback=true)
, you don't have to rollback the transaction manually.Context.setRollbackOnly()
forces the container to rollback the transaction, also if there is no exception. - A checked exception itself doesn't rollback a transaction. It needs to have the annotation
@ApplicationException(rollback=true)
. If the exception is aRuntimeException
and the exception isn't caught, it forces the container to rollback the transaction. But watch out, the container will in this case discard the EJB instance. - As mentioned in 2.), if you throw a
RuntimeException
, the transaction will be rolled back automatically. If you catch an checked exception inside the code, you have to usesetRollbackOnly
to rollback the transaction.
- 如果使用 抛出异常
@ApplicationException(rollback=true)
,则不必手动回滚事务。Context.setRollbackOnly()
强制容器回滚事务,如果没有异常也是如此。 - 已检查异常本身不会回滚事务。它需要有注释
@ApplicationException(rollback=true)
。如果异常是 aRuntimeException
并且没有捕获到异常,它会强制容器回滚事务。但请注意,在这种情况下,容器将丢弃 EJB 实例。 - 如 2.) 中所述,如果抛出
RuntimeException
,事务将自动回滚。如果在代码中捕获了已检查的异常,则必须使用setRollbackOnly
来回滚事务。
For further information, check out the free book Mastering EJB. It describes the rollback scenarios very well and is free for download.
如需更多信息,请查看免费书籍Mastering EJB。它很好地描述了回滚方案,并且可以免费下载。
回答by Christian Gosch
The question of how to prevent checked exceptions annotationally declared to cause a rollback on throwing from being propagated to the "upper layer" is not yet answered here.
如何防止以注释方式声明的检查异常导致抛出回滚传播到“上层”的问题尚未在这里回答。
I think that this will require a wrapper around the EJB in question which swallows the thrown exception. (In other words: I think that the custom exception MUST be thrown against method boundary (and thus not catched & processed inside the method) AND propagated to take transactional effect -- and also will in turn cause destruction of the EJB instance.)
我认为这将需要在所讨论的 EJB 周围进行包装,从而吞下抛出的异常。(换句话说:我认为自定义异常必须针对方法边界抛出(因此不能在方法内部捕获和处理)并传播以产生事务效果——并且还会反过来导致 EJB 实例的破坏。)