0

I have been asked this question many times and is bugging me for long now.

We have a service class with 3 DAO methods updating 3 different tables. The design is such that update to all three tables should be atomic. I have 3 threads invoking my service class separately and for each DAO method update, how do I use Spring transactions or any transaction manager to keep all threads (operations) under a single transaction ?? Any ideas or pointers to documentation ?? Thanks !!

Dibjot
  • 21
  • 1
  • 1
  • 1

2 Answers2

1

This can be achieved by keeping transaction at thread level. However u would require a shared object between all those threads. This shared object will keep a track of status of all this threads and notify them if either fails. If failure notification is recieved by this threads they themselves can throw an exception and their transaction will be rollbacked.

Example code

Code in individual threads

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

Code in shared class

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

Here the failure condition is if any of thread is saving data with id 5 all threads will rollback their code. Else all will succeed

payne
  • 4,691
  • 8
  • 37
  • 85
Vicky Desai
  • 223
  • 1
  • 3
  • 9
0

Service method should to be the one that starts the transactions

Service Method

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(){

      }
    }

Similarly the Dao2 and Dao3

someUpdate() will use the transaction started by someMethod() of the Service.class

Neelam Mehta
  • 186
  • 5
  • Thanks for your response. If I understand your solution correct, the three dao methods are run by a single thread which invokes somemethod() in a trasanction. My problem is to execute the three methods separately (concurrently) using 3 threads. Any suggestions ? – Dibjot Oct 13 '14 at 09:03
  • did you found an answer ? – Pri_stack Jan 24 '20 at 10:24