2011-12-30 114 views
0

我創建了一個簡單的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注入。

+0

你應該打開一個博客分享你的發現。 StackOverflow是爲了提出問題。 – 2011-12-30 11:54:23

回答

-1

在@Transactional之後使用@TransactionConfiguration("name",ROLLBACK); //check syntax,同時聲明TrxHandleAnnotated。有關@Transcational及其用法的更多信息,請參見this link