1

我在 Spring 中处理事务时遇到问题。我有一个 Web 服务,它简单地迭代一定次数,每次都将一条记录插入到 Oracle 数据库中。我将我的服务的插入方法标记为@Transactional,因为我希望它在任何插入失败时回滚(在运行时异常之后,即在要插入空对象的情况下)。

问题是,如果我通过 java 测试服务,使用通过 Spring 应用程序上下文实例化服务的 main,evertything 工作正常(我得到每条记录回滚)。相反,如果我使用soapUI 测试Web 服务,则在将其部署到本地服务器后,就像看不到@Transactional 注释一样。

我报告我的代码。

这是我的服务:

@Service
public class MyService{

        @Transactional
        public void insert(List<DAO> l) {

              for(DAO item : l) {
              //Insert item into the DB
              //and throw a RunTimeException in case of failure (i.e.,item null)
              }
        }
}

这是我的主要内容:

public class TestMain{

    public static void main(String[] args) {

        ApplicationContext ac = new FileSystemXmlApplicationContext(SPRING_CONTEXT_XML_PATH);

        MyService service = ac.getBean(MyService .class);

        List<DAO> l; //Suppose it is initialized    
        service.insert(l); //Rollback working if RuntimeException is thrown     
}

}

正如我所说,当我使用 Spring 应用程序上下文实例化 Web 服务时,上面的代码可以工作,但是如果我在将 MyService 部署在服务器上之后通过soapUI调用它(这实际上是服务的目的),@Transactional 不是执行。

有人可以向我解释这种行为吗?

非常感谢。

4

1 回答 1

0

每次insert调用该方法时,spring都会为您启动一个事务,因为它具有@Transactional注释。当insert返回时事务被提交(或者如果抛出异常则回滚)。

当 spring 创建一个 type 的 bean 时MyService,它用这样的东西包装insert方法:

EntityManager em = ...; // get EntityManager here
EntityTransaction tx = null;
try {
    tx = em.getTransaction();
    tx.begin();

    // your insert method is called here.

    tx.commit();
} catch (Exception e) {
    if ( tx != null && tx.isActive() ) {
        tx.rollback();
    }
}

soupUI 不处理@Transactional注释。您必须自己启动事务并提交/回滚。

于 2012-11-14T11:02:12.600 回答