最近写spring事务时用到REQUIRES_NEW遇到一些不回滚的问题,所以就记录一下。
场景1:在一个服务层里面方法1和方法2都加上事务,其中方法二设置上propagation=Propagation.REQUIRES_NEW,方法1调用方法2并且在执行完方法2后抛出一个异常,如下代码
1 @Service 2 public class BookServiceImpl implements BookService { 3 4 @Autowired 5 private JdbcTemplate jdbcTemplate; 6 7 @Transactional(timeout=4) 8 public void update() { 9 // TODO Auto-generated method stub 10 //售卖 扣除库存数量 11 String sellSql = "UPDATE book_stock SET stock = stock - ? WHERE isbn = (SELECT isbn FROM book WHERE NAME = ?)"; 12 //入账的sql 将赚到的钱添加到account表中的balance 13 String addRmbSql = "UPDATE account SET balance = balance + ? * (SELECT price FROM book WHERE NAME = ?)"; 14 Object []params = {1,"Spring"}; 15 16 jdbcTemplate.update(sellSql, params); 17 18 testUpdate(); 19 20 jdbcTemplate.update(addRmbSql, params); 21 22 throw new RuntimeException("故意的一个异常"); 23 } 24 @Transactional(propagation=Propagation.REQUIRES_NEW) 25 public void testUpdate() { 26 //这个业务没什么意义,只是用来测试REQUIRES_NEW的 当执行后SpringMVC这本书库存-1 27 String sql = "UPDATE book_stock SET stock = stock - ? WHERE isbn = (SELECT isbn FROM book WHERE NAME = ?)"; 28 Object []params = {1,"SpringMVC"}; 29 jdbcTemplate.update(sql, params); 30 31 }
三张表分别是对应account表,book表,book_stock表
1 private static ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring/*.xml"); 2 3 @Test 4 public void testREQUIRES_NEW() { 5 6 BookService bean = ac.getBean(BookService.class); 7 8 bean.update(); 9 }
结果是无论是方法1还是方法2都回滚了,那么REQUIRES_NEW就不起作用了,为了探索原因我修改了一下代码
在第5行的地方打印出对象的类型是