将其抛入sendMsg()方法后,您将捕获RuntimeException。除非它被抛出堆栈,否则Exception不会触发事务回滚。使用Container托管事务时,容器会向方法调用添加拦截器,以便在抛出未经检查的异常时设置事务并处理回滚。如果未从方法中抛出异常,则拦截器不知道它需要将事务作用回来。
编辑1:
请注意,只抛出RuntimeException或RuntimeException的子类将导致事务回滚。检查异常(扩展Exception而不是RuntimeException)将不会导致回滚,除非使用@ApplicationException(rollback = true)进行批注。
另一种方法是注入EJBContext对象,并调用.setRollbackOnly()以在方法超出范围时强制事务回滚:
@Stateless public class SomeEjb { @Resource private EJBContext context; @TransactionAttribute(TransactionAttributeType.MANDATORY) public void rollMeBack() { context.setRollbackOnly(); } }