在EJB项目中,对于特定的例外,我想仍然保留当前正在回滚的实体。在异常块中创建和刷新实体无济于事。交易仍回滚。 我试图将实体与当前事务分离,并将其保留在新事务中。但这会导致“另一个事务管理的实体”错误。 我该如何实现?
该项目基于带有EJB 3.1的JEE6构建。持久性在于OpenJPA。
答案 0 :(得分:0)
将该位换成
boolean itWorked = true;
try {
// .. persistence operation which throws exception
} catch (YourFavouriteException yfe) {
itWorked = false;
}
if (!itWorked) {
// try it again (the definition of insanity)
}
确保您没有捕获一般异常,而仅捕获特定异常(由于某种原因,这意味着持久化仍然有效)
答案 1 :(得分:0)
EJB 3.1 spec在第14.2.1节中描述了如何完成此操作:
Bean Provider定义应用程序异常。可以通过在bean的业务接口,无接口视图,主接口,组件接口和Web服务端点的方法的throws子句中列出来定义应用程序异常(即检查异常)。应用程序异常是未经检查的异常,通过使用注释将其定义为应用程序异常。 ApplicationException元数据批注,或在部署描述符中表示它 带有application-exception元素
和
除非将ApplicationException批注应用于异常类并使用rollback元素值true或指定的异常,否则应用程序异常不会自动导致将事务标记为回滚。 异常的application-exception部署描述符元素将rollback元素指定为true。 [...]
在从企业bean实例引发应用程序异常之前,Bean Provider必须执行以下操作之一以确保数据完整性:
- 确保实例处于这样的状态:客户端尝试继续和/或提交事务不会导致数据完整性损失。例如,该实例引发应用程序异常,指示该实例执行任何数据库更新之前输入参数的值无效。
- 如果未指定应用程序异常导致事务回滚,请在引发应用程序异常之前使用EJBContext.setRollbackOnly方法将事务标记为回滚。将交易标记为回滚将确保该交易永远不会提交。
也就是说,如果您希望在引发异常时提交事务,则必须将该异常指定为应用程序异常。
或者您可以启动一个单独的事务,但是由于JEE不支持嵌套事务,因此只有在上一个事务完成后才有可能。