为什么我的 spring @Transactional with REQUIRED 不能回滚?
Why my spring @Transactional with REQUIRED can't rollback?
我尝试编写一个非常简单的代码来测试@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() 不在同一个事务中,但我想要的是所有要回滚的东西。请帮忙
@Transactional
对 testPro()
无效,原因有 3 个:
testPro()
是静态的。
- 来自同一 class 的
test()
的内部调用。
- class
cases
的实例不是由 Spring 创建的。
这意味着 add()
和 delete()
是 运行 在两个单独的事务中。
为了证明这一点,尝试将 delete()
上的传播更改为 MANDATORY
。它现在会抛出异常,说明交易没有进行 (或类似的东西).
我尝试编写一个非常简单的代码来测试@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() 不在同一个事务中,但我想要的是所有要回滚的东西。请帮忙
@Transactional
对 testPro()
无效,原因有 3 个:
testPro()
是静态的。- 来自同一 class 的
test()
的内部调用。 - class
cases
的实例不是由 Spring 创建的。
这意味着 add()
和 delete()
是 运行 在两个单独的事务中。
为了证明这一点,尝试将 delete()
上的传播更改为 MANDATORY
。它现在会抛出异常,说明交易没有进行 (或类似的东西).