我创建了一个简单的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