Reputation: 13
I try to write a very simple code to test @Transactional, but it won't rollback when I use Propagation.REQUIRED. Here is the code.
@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();
}
}
When I test add() method alone by creating a new RuntimeException(), it will rollback. This is what I expected. However, when I run the test() method, the add() method won't rollback when delete() throws a new RuntimeException. It means the add() and delete() are not in a same transaction, but what I want is all the things to be rollback. Please help.
Upvotes: 1
Views: 439
Reputation: 159114
@Transactional
on testPro()
has no effect for 3 separate reasons:
testPro()
is static.test()
in same class.cases
not created by Spring.That means that add()
and delete()
are running in two separate transactions.
To prove it, try changing the propagation on delete()
to MANDATORY
. It will now throw exception saying that transaction is not in progress (or something to that effect).
Upvotes: 6