12

In an interview someone asked me : How do we manage 2 transactional/dao methods in a single transaction. Desired capabilities:

  1. If anyone of them fails we need to rollback both methods.
  2. Both of the methods can be called separately attached with a single transaction.
  3. The management should be on DAO layer, not on service layer.

I think : the question relates to spring transaction management.

Satish Pandey
  • 1,340
  • 3
  • 10
  • 20

3 Answers3

13

First of all, transaction management should be done on service layer, not on DAO layer as that would create a lot of performance overhead (to deal with appropriate transaction isolation level and propagation at each different method). Also, the scope of a unit of work comes from the service layer instead of the data access layer: imagine performing a business process that needs to deal with 2 or more DAOs.

There is a lot of discussion in the Internet that points in that direction as here, here and here.

Anyway, since it's an interview let's accept the question as is. From my point of view, you would be using the @Transactional annotation (or the XML configuration) in both methods and with a transaction propagation with REQUIRED value. That way, when any of those methods is invoked and if no previous transaction exist, a new transaction will be created:

@Transactional
class MyDAO {

   @Transactional(propagation = REQUIRED)
   public void foo() {
   }

   @Transactional(propagation = REQUIRED)
   public void bar() {
   }

}
  • Is it means `foo()` and `bar()` share the same transaction and if 1 fail another 1 will also rollback? Can you provide some clarification? – Satish Pandey Sep 04 '12 at 15:37
  • well, each method declares its own unit of work: tx will be committed at the end of each method and if any of them throws an exception it will be rolled-back. – Alonso Dominguez Sep 04 '12 at 16:00
  • so we need to add `@Transactional(propagation = REQUIRED)`in DAO layer method for propagation and `@Transactional` on service layer, but if I put `@Transactional` on service layer only instead of putting in on DAO layer, what is difference? – atish shimpi Sep 15 '15 at 07:43
  • `propagation = REQUIRED` is the default value for the transactional annotation propagation, so it isn't neccesary to write it. – Daniel Higueras Aug 04 '16 at 08:58
2

Ignoring spring and frameworks in my answer..... just the basic idea of using function parameters. I'm sure the concept could apply within [insert framework here].

You would need to handle the commit/rollback outside of the 2 DAO methods. The 2 methods would need to take the transaction/connection as input.

psuedo code:

bool method1(Tran t) { /* stuff */}
bool method2(Tran t) { /* stuff */ }

callingMethod() {
     Tran t = null;
     try {
         t = new Conn().open().startTran();
         if(method1(t) && method2(t))
             t.commit();
         else
             t.rollBaack();
     }
     catch(ex) {  t.rollBack();  }
     finally {  t.closeConn();  }
}
mike30
  • 2,788
  • 2
  • 16
  • 19
  • 1 question : why we are passing `Tran t` as a parameter with both methods. Can you provide some explanation? – Satish Pandey Sep 04 '12 at 15:27
  • @Satish, because in the question (item #1 and #2), the DAO methods need to have the flexibility to be called independently as well as dependently. If you commit inside method1 with a local-scope transaction then you could not roll back if something went wrong in method2 as you have already committed method1 before method2 was invoked. – mike30 Sep 04 '12 at 16:13
0

There is a chance that two methods should work independently also at the same time there might run in a same transaction.So we need to use Propagation-Required. If the transaction has to run in same transaction then it will use the first transaction else a new transaction is created if invoked independently. Correct me if I am wrong.