2011-12-30 110 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