为什么我的春天@Transactional与REQUIRED无法回滚?

时间:2016-12-31 19:19:32

标签: java spring transactional

我尝试编写一个非常简单的代码来测试@Transactional,但是当我使用Propagation.REQUIRED时它不会回滚。这是代码。

    @Component
    public class A {

        private JdbcTemplate jdbcTemplate;

        @Resource(name="dataSource")
        public void setDataSource(DataSource dataSource) {
            this.jdbcTemplate = new JdbcTemplate(dataSource);
        }

        @Transactional(propagation=Propagation.REQUIRED)
        public void add(Person person) throws Exception {
        try {
            String sql = "insert into person (id, name) values(?,?)";
            jdbcTemplate.update(sql, new  Object[{person.getId(),person.getName()});
        } catch (Exception e) {
            throw new RuntimeException();
        }

        @Transactional(propagation=Propagation.REQUIRED)
        public void delete(String id) throws Exception {
            throw new RuntimeException();
            ***throw a RuntimeException on purpose***
        }
    }

    public class cases {

        @Transactional
        public static void testPro() throws Exception {
        try {
            AbstractApplicationContext aac = new ClassPathXmlApplicationContext("beans.xml");
            A a = (A) aac.getBean("a");
            a.add(***a random person***);
            a.delete("99");
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    @Test
    public void test() throws Exception {
        testPro();
    }
}

当我通过创建一个新的RuntimeException()来单独测试add()方法时,它将回滚。这是我的预期。但是,当我运行test()方法时,add()方法在delete()抛出新的RuntimeException时不会回滚。这意味着add()和delete()不在同一个事务中,但我想要的是所有要回滚的东西。请帮忙。

1 个答案:

答案 0 :(得分:6)

@Transactional上的{p> testPro()因3个不同原因而无效:

  1. testPro()是静态的。
  2. 来自同一班级的test()内部通话。
  3. cases的实例不是由Spring创建的。
  4. 这意味着add()delete()正在两个单独的交易中运行。

    要证明这一点,请尝试将delete()上的传播更改为MANDATORY。它现在将抛出异常,表示事务未在进行中(或其他类似的事情)