Spring Transaction propagation REQUIRED, REQUIRES_NEW

后端 未结 3 630
梦谈多话
梦谈多话 2021-01-07 06:08

in following code method doService1() update correct sql but doService2() sql has some issue , but when i call doService() it has to c

相关标签:
3条回答
  • 2021-01-07 06:11

    I had the same problem earlier and it was solved here : Strange behaviour with @Transactional(propagation=Propagation.REQUIRES_NEW)

    Using default setting, there won't be any new transaction proxy created when you call doService2() from the same class, as a result your annotation is not user.

    To avoid this issue you can put doService2() in another class or use aspectJ for transaction by declaring it like this : <tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>

    Best solution will depend on your application. (The second one here seems more appropriate)

    0 讨论(0)
  • 2021-01-07 06:30

    The call to doService2() probably doesn't have any transaction advice running on it because I'm assuming you're using a JDK dynamic proxy (interface proxy) instead of CGLIB based proxies. If you don't already know about how this works you might want to read: http://static.springsource.org/spring/docs/3.0.x/reference/aop.html#aop-proxying .

    If you're not using CGLIB (target-class proxying), it will never go through the Spring Transaction advisor when you call doService2() since it is invoking the method directly instead of going through the wrapper Spring creates for your service at startup time.

    You can get your example working by moving doService2() to a different service class then injecting it on to this service. That way you'll be going through the proxy and the transaction advice will run.

    Otherwise, if you're ready to make a bigger change to your project, you could get your example to work as-is: 1) make sure CGLIB is in your classpath, and 2) turn on proxy-target-class , or force it to use CGLIB proxying so by getting rid of your service interface.

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
    

    If you're going to do this, make sure you're read through the first link :).

    0 讨论(0)
  • 2021-01-07 06:36

    According to spring documentation(Check section 10.5.6.1),the spring framework transaction will Rollback for only RunTimeException.
    Not for other checked excpetions like SqlException. So if you really want a rollback for this exception you have to specify it like below

    @Transactional(propagation=Propagation.REQUIRES_NEW,rollbackFor=SQLException.class)
    public void doService2(){
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "  update aa set a_name = 'hhh' where a_id = 4 and " ;
        int rowCount1 =  jdbcTemplate.update(sql);
        System.out.println(" rowCount2 >" + rowCount1);
    }
    

    Try this and let me know if it works.
    Also this might help more.

    0 讨论(0)
提交回复
热议问题