I have a service that has several methods marked with @Transactional, including methods a, b and c. These 3 methods are nested in the following way a -> b -> c. Here is a code sample:
@Transactional
public void a() {
while(condition) {
try {
b();
} catch(MyException e) {
logger.warn(e.getMessage());
}
}
}
Method b however is annotated like this:
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {MyException.class})
However, when MyException is thrown from method c, the exception is caught at method a and when that exits, the transaction is comitted and that includes whatever has been done by call to b() that threw the exception and should have been rolled back(?).
I am using sql server 2012 express with spring 3.0.7 and my spring configuration is like this:
<tx:annotation-driven />
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<qualifier value="txm1"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/jpa-persistence.xml"/>
<property name="persistenceUnitName" value="Unit1" />
</bean>
Method
bseems to be in the same class as methoda. If you’re not using AspectJ, the@Transactional-annotations are handled by a JDK dynamic proxy, through which your calls from outside the class travel to methoda. The call needs to travel through the proxy for the@Transactional-annotations to have effect, see for example here, under ‘Understanding AOP proxies’: http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch08s06.html