0

我创建了一个简单的 Spring 应用程序来测试 Spring 声明式事务的基础知识。根据规则,声明性事务应在 RuntimeException 的情况下回滚。但就我而言,它并没有回滚。

主要测试类有代码

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();
}

这对我来说是一个教训,除非另有要求,否则整个应用程序应该只使用一个上下文对象。

这听起来太明显了 Spring 从业者,但像我这样的 Spring 新手会犯这种愚蠢的错误。于是想到分享。

在这种特殊情况下,最好将其声明为成员变量并使用 setter 注入,而不是手动创建 JdbcTemplate。

4

1 回答 1

-1

@TransactionConfiguration("name",ROLLBACK); //check syntax在声明时在 @Transactional 之后使用TrxHandleAnnotated. 有关@Transcational 及其用法的更多信息,请参阅此链接。

于 2011-12-30T11:56:08.797 回答