Transaction marked as rollback only: How do I find the cause

后端 未结 8 1637
深忆病人
深忆病人 2020-11-28 19:39

I am having issues with committing a transaction within my @Transactional method:

methodA() {
    methodB()
}

@Transactional
methodB() {
    ...
    em.pers         


        
相关标签:
8条回答
  • 2020-11-28 19:55

    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.

    0 讨论(0)
  • 2020-11-28 20:03

    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

    0 讨论(0)
  • 2020-11-28 20:04

    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 ;)

    0 讨论(0)
  • 2020-11-28 20:06

    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

    0 讨论(0)
  • 2020-11-28 20:08

    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.

    0 讨论(0)
  • 2020-11-28 20:11

    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();
    
    0 讨论(0)
提交回复
热议问题