我无法避免在RuntimeException之后阻止事务回滚。我的环境是在Websphere 8.0上运行的Spring 4.1 + Hibernate 3.6 + JTA(WebSphereUowTransactionManager)。
首先,一个简单的情况表现出预期的效果。由于我 捕获了RuntimeException ,因此事务提交并成功创建了新资源。
@Service("fooService") public class FooServiceImpl implements IFooService { @Transactional @Override public void doStuff(Resource res){ authService.createResource(res, "ADMIN"); try { throw new RuntimeException("SOMETHING"); } catch (RuntimeException e) { e.printStackTrace(); } }
下一个也可以。我声明了 noRollbackFor ,让我们提交事务:
@Transactional(noRollbackFor=RuntimeException.class) @Override public void doStuff2(Resource res){ authService.createResource(res, "ADMIN"); throw new RuntimeException("SOMETHING"); }
最后是有问题的。区别在于,在这种情况下,对的第二次调用会引发异常authService.createResource。仅供参考,authService.createResource仅标记为@Transactional,因此默认传播配置适用,并且应加入调用服务的事务。
authService.createResource
@Transactional(noRollbackFor=RuntimeException.class) @Override public void doStuff12(Resource res){ authService.createResource(res, "ADMIN"); try{ res.setName("EXISTING-RESOURCE"); authService.createResource(res, "ADMIN"); }catch(RuntimeException e){ e.printStackTrace(); } }
尽管 捕获了RuntimeException并声明了noRollbackFor 属性,但该事务始终回滚。任何解释吗?
日志跟踪信息:
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',+com.myorg.webapps.exception.ElementoYaExistente org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=false org.springframework.transaction.support.TransactionSynchronizationManager TRACE - Initializing transaction synchronization org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.test.service.impl.FooServiceImpl.doStuff12] org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=true org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.authmgr.service.impl.AuthorizationServiceImpl.createResource] org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=true org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=true org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.authmgr.service.impl.AuthorizationServiceImpl.createResource] org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - Applying rules to determine whether transaction should rollback on java.lang.Runtime: Couldn't create the resource, it already exists: EXISTING-RESOURCE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - Winning rollback rule is: null org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - No relevant rollback rule found: applying default rules org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=true org.springframework.transaction.jta.WebSphereUowTransactionManager TRACE - Triggering beforeCommit synchronization org.springframework.transaction.jta.WebSphereUowTransactionManager TRACE - Triggering beforeCompletion synchronization org.springframework.transaction.support.TransactionSynchronizationManager TRACE - Clearing transaction synchronization org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=false
据我所知,一旦从事务方法中抛出运行时异常并被事务拦截器拦截,则该事务将被标记为仅回滚。即使从另一个事务方法调用此事务方法。
这对我来说很有意义:如果内部方法无法从异常中恢复,则无法恢复,而外部方法则不应像没有任何反应那样进行。
如果您希望交易不会回滚,则可以