I am having issues with committing a transaction within my @Transactional method:
methodA() {
methodB()
}
@Transactional
methodB() {
...
em.pers
I finally understood the problem:
methodA() {
methodB()
}
@Transactional(noRollbackFor = Exception.class)
methodB() {
...
try {
methodC()
} catch (...) {...}
log("OK");
}
@Transactional
methodC() {
throw new ...();
}
What happens is that even though the methodB
has the right annotation, the methodC
does not. When the exception is thrown, the second @Transactional
marks the first transaction as Rollback only anyway.
I struggled with this exception while running my application.
Finally the problem was on the sql query. i mean that the query is wrong.
please verify your query. This is my suggestion
disable the transactionmanager in your Bean.xml
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
comment out these lines, and you'll see the exception causing the rollback ;)
apply the below code in productRepository
@Query("update Product set prodName=:name where prodId=:id ")
@Transactional
@Modifying
int updateMyData(@Param("name")String name, @Param("id") Integer id);
while in junit test apply below code
@Test
public void updateData()
{
int i=productRepository.updateMyData("Iphone",102);
System.out.println("successfully updated ... ");
assertTrue(i!=0);
}
it is working fine for my code
Found a good explanation with solutions: https://vcfvct.wordpress.com/2016/12/15/spring-nested-transactional-rollback-only/
1) remove the @Transacional from the nested method if it does not really require transaction control. So even it has exception, it just bubbles up and does not affect transactional stuff.
OR:
2) if nested method does need transaction control, make it as REQUIRE_NEW for the propagation policy that way even if throws exception and marked as rollback only, the caller will not be affected.
Look for exceptions being thrown and caught in the ...
sections of your code. Runtime and rollbacking application exceptions cause rollback when thrown out of a business method even if caught on some other place.
You can use context to find out whether the transaction is marked for rollback.
@Resource
private SessionContext context;
context.getRollbackOnly();