2

We have upgraded spring version to 4.3.9 and after upgrading we are getting transaction rollback exception

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:125)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy65.bulkDeleteAreas(Unknown Source)
at com.nis.compass.test.functional.geocoding.GeocodingManagerTestHelper.bulkDeleteAreas(GeocodingManagerTestHelper.java:188)

here is the xml configuration for the bean and the parent transactionProxy bean. We have not changed anything in the xml but still it is throwing transaction exception.

  <bean id="geocodingManager" parent="baseTransactionProxy">
<property name="target">
  <bean class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces">
      <value>com.nis.compass.geocoding.service.GeocodingManagerInternal</value>
    </property>
    <property name="target" ref="geocodingManagerImpl" />
    <!-- list of interceptors, "Advice"s, and Advisors to add to the interceptor chain -->
    <property name="interceptorNames">
      <list>
        <value>performanceMonitorProxy</value>
      </list>
    </property>
  </bean>
</property>

  <bean id="baseTransactionProxy" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
  <ref local="compassTransactionManager" />
</property>
<property name="transactionAttributes">
  <props>
    <!-- Always propagate transaction, rolling back on any checked or unchecked exception -->
    <prop key="*">PROPAGATION_REQUIRED,-Throwable</prop>
  </props>
</property>
<property name="preInterceptors">
  <list>
    <bean class="com.nis.compass.common.interceptor.ExceptionTranslationInterceptor" />
  </list>
</property>

Deepak Pandey
  • 618
  • 7
  • 19
  • I am a bit off topic there but would you have some link with information to migrate from spring 1 to 4 or at least to 3 ? – Xavier Bouclet Sep 03 '19 at 18:01
  • 1
    I don't think there are changes you should be worried about while migrating to 3. I migrated from spring 1.2 to version 4.3 and it was smooth without much code changes. the major changes were done in Spring 5. many deprecated API were removed. Please check this [Upgrading to Spring Framework 5.x](https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-5.x) – Deepak Pandey Sep 04 '19 at 09:28

1 Answers1

1

I think it's just an improvment in log between the 2 versions. The functional behaviour is probably the same.

And this behaviour is normal as stated in the PROPAGATION_REQUIRED documentation

However, in the case where an inner transaction scope sets the rollback-only marker, the outer transaction has not decided on the rollback itself, and so the rollback (silently triggered by the inner transaction scope) is unexpected. A corresponding UnexpectedRollbackException is thrown at that point. This is expected behavior so that the caller of a transaction can never be misled to assume that a commit was performed when it really was not. So if an inner transaction (of which the outer caller is not aware) silently marks a transaction as rollback-only, the outer caller still calls commit. The outer caller needs to receive an UnexpectedRollbackException to indicate clearly that a rollback was performed instead.

You can also read this related post that summarize what is written in the doucmentation : UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

alain.janinm
  • 19,951
  • 10
  • 65
  • 112
  • 1
    The issue is resolved now. The bean "geoCodingManager" was calling another api "locationManagerWithNewTransaction" which was declared as follows [spring-app-context.xml](https://gist.github.com/depandey/4a64db3a2a978d3ddce61050a19da802#file-spring-app-context-xml) so, instead of calling the above api where it was creating a new trasaction. I declared a new bean where it did not had any trasaction declared explicitly. – Deepak Pandey Jan 30 '19 at 04:50