使用具有多个线程的Spring Transactions

时间:2014-10-09 11:43:04

标签: java multithreading spring spring-mvc transactions

我多次被问到这个问题并且现在很烦我。

我们有一个服务类,其中包含3个DAO方法,可以更新3个不同的表。 设计是这样的,所有三个表的更新应该是原子的。 我有3个线程分别调用我的服务类,并为每个DAO方法更新, 如何使用Spring事务或任何事务管理器将所有线程(操作)保留在单个事务下? 任何想法或指向文档? 谢谢!!

2 个答案:

答案 0 :(得分:0)

服务方法应该是启动交易的方法

服务方法

public class Service{
// define dao1,dao2,dao3
@Transactional
public someMethod(){
   dao1.someUpdate();
   dao2.someUpdate();
   dao3.someUpdate();
}
}

Dao1.class

 public class Dao1{

      @Transactional (propagation = Propagation.MANDATORY)
      public someUpdate(){

      }
    }

类似于Dao2和Dao3

someUpdate()将使用Service.class的someMethod()启动的事务

答案 1 :(得分:0)

这可以通过将事务保持在线程级别来实现。但是,你需要所有这些线程之间的共享对象。此共享对象将跟踪所有此线程的状态,并在其中一个失败时通知它们。如果此线程收到失败通知,则他们自己可以抛出异常,并且它们的事务将被回滚。

示例代码 各个线程中的代码

@Transactional(rollbackFor = Exception.class)
public void saveData(Product product, ProductStatusObject productStatusObject) throws Exception {
    productDao.persist(product);
    if(product.getId() == 5) {
        productStatusObject.updateCounter(false);
    } else {
        productStatusObject.updateCounter(true);
    }
    if(!productStatusObject.getStatus()) {
        throw new Exception();
    }
}

共享类中的代码     private final int totalThreads;

private int executedThreads = 0;
private Boolean finalStatus = true;

public ProductStatusObject(int totalThreads) {
    this.totalThreads = totalThreads;
}

public synchronized void updateCounter(Boolean threadStatus) throws InterruptedException {
    executedThreads ++;
    if(!threadStatus) {
        this.finalStatus = false;
    }
    if(totalThreads == executedThreads) {
        notifyAll();
    } else {
        wait();
    }

}

public synchronized Boolean getStatus() {
    return finalStatus;
}

这里的失败条件是,如果任何线程正在保存id为5的数据,则所有线程都将回滚其代码。否则一切都会成功