我創建了一個簡單的Spring應用程序來測試Spring聲明性事務的基礎知識。 按照規則聲明式事務應該在RuntimeException的情況下回滾。 但我的情況並沒有回滾。Spring聲明性事務不回滾
主要測試類有代碼
public class SpringOraTest {
public static void main(String[] args) {
ApplicationContext aplctx= new
FileSystemXmlApplicationContext("src\\config\\SpringConfigForOra.xml");
//Call to test Declarative Transaction with Annotation
TrxHandleAnnotated prxyobj=((TrxHandleAnnotated)aplctx.getBean("dbCommandAnnotated"));
prxyobj.doTask();
}
}
類TrxHandleAnnotated有代碼: -
@Transactional
public class TrxHandleAnnotated
public void doTask(){
ApplicationContext aplctx= new
FileSystemXmlApplicationContext("src\\config\\SpringConfigForOra.xml");
JdbcTemplate jdbcTemplate= (JdbcTemplate)aplctx.getBean("jdbcTemplate");
jdbcTemplate.update("insert into kau_emp values(4,'forthmulga')");
throw new RuntimeException();
}
並有需要配置XML配置。
我期待在拋出異常時回滾事務。但它沒有回滾,並且記錄被提交給DB。
即使經過漫長的互聯網搜索,我不明白爲什麼它不會回滾。
後來我意識到,在doTask()代碼中,我再次創建上下文並將我們的JdbcTemplate實例帶出新的上下文。這是問題的根源。
我改變了代碼,使得兩個類都使用了一些上下文。它的工作!
public class SpringOraTest {
public static ApplicationContext aplctx;
public static void main(String[] args) {
aplctx= new FileSystemXmlApplicationContext("src\\config\\SpringConfigForOra.xml");
//Call to test Declarative Transaction with Annotation
TrxHandleAnnotated prxyobj=
((TrxHandleAnnotated)aplctx.getBean("dbCommandAnnotated"));
prxyobj.doTask();
}
@Transactional
public class TrxHandleAnnotated
public void doTask(){
JdbcTemplate jdbcTemplate=(JdbcTemplate)SpringOraTest.aplctx.getBean("jdbcTemplate");
jdbcTemplate.update("insert into kau_emp values(4,'forthmulga')");
throw new RuntimeException();
}
對我來說,這是一個教訓,除非另有要求,整個應用程序應該只使用一個上下文對象。
這聽起來太明顯了春天的練習者,但像我這樣的春季新手可以犯這樣的愚蠢錯誤。所以想到分享它。
在這種特殊情況下,不是手動創建JdbcTemplate,而是將其聲明爲成員變量並使用setter注入。
你應該打開一個博客分享你的發現。 StackOverflow是爲了提出問題。 – 2011-12-30 11:54:23