Spring Transaction propagation REQUIRED, REQUIRES_NEW

亡梦爱人 提交于 2019-12-01 09:38:50
DessDess

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)

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 :).

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!