一个UnexpectedRollbackException异常解决

来源:互联网 发布:起点数据为 编辑:程序博客网 时间:2024/06/05 05:13

背景

2014-10-08号早上06:50之后,系统一直在报UnexpectedRollbackException异常。

stackTrace:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:718) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy76.executeStatisticUserHandleRank(Unknown Source) 

原因分析

碰到的问题大概可以简化成下面这样,伪代码大致如下:

ClassA.method(){

  begin transaction;

beforeDone();

try
{
  classB.doSomething(); //这里面有非受检异常抛出,所以标记为回滚, doSetRollbackOnly(status);

}catch(RuntimeException e)
{
}

afterDone();
  commit;
  end;

}


ClassB.doSomething()伪代码:

 ClassB.doSomething(){

    begin transaction;
          /**  do anything  */     //这里会抛出一个runtime 的非受检异常
          commit;
          end;

 }

这个是一个事务嵌套事务的例子,在spring里面我们配置了事务的传播机制是REQUIRED,所以这两个事务最终会合并成一个事务。程序中doSomething()中由于某某原因导致抛出异常(或者明确将该事务设置为了RollbackOnly),因为事务嵌套,ClassA.method()中有非受检异常抛出,标记并直接回滚,ClassB.doSomething()中有受检异常抛出,只是标记回滚状态,在调用回ClassA.method()中回滚,这个方法中ClassB.doSomething()有受检异常抛出,事务被标记为回滚,继续执行到ClassA.method(), 可是被捕获了,也就不回滚了,一直执行到最后commit。在commit时spring会判断回滚标志,若有回滚标记,回滚并抛出UnexpectedRollbackException异常,ransaction rolled back because it has been marked as rollback-only。

 


0 0
原创粉丝点击