ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Niels Beekman" <n.beek...@wis.nl>
Subject RE: Transaction question
Date Sat, 20 Aug 2005 13:27:42 GMT
I agree, the whole purpose of iBATIS is to take away all this messy
coding with delegates and what all. It would require thorough
understanding of the way transactionhandling works in combination with
iBATIS. Simple reuse of methods like the example Brian mentions is
impossible just because of you made the "mistake" of executing it
transactioned...

Niels

-----Original Message-----
From: Barnett, Brian W. [mailto:brian.barnett@pearson.com] 
Sent: donderdag 18 augustus 2005 18:25
To: 'user-java@ibatis.apache.org'
Subject: RE: Transaction question

Prashanth,
Your suggestion is precisely what I did on a previous project. (The
"service
delegate" mentioned below.) I had a whole slug of methods whose sole
responsibility was to start and end transactions, and it got cumbersome.
For
example, I might have an updateWidget() method in a service layer class.
I
then would also have an updateWidget() in the "service delegate" to
provide
the transaction handling which turns around and calls updateWidget() in
the
service layer... a proliferation of methods.

It is this proliferation of methods that I want to get away from.

-----Original Message-----
From: Prashanth Sukumaran [mailto:prashanthsukumaran@yahoo.com] 
Sent: Thursday, August 18, 2005 10:15 AM
To: user-java@ibatis.apache.org
Subject: RE: Transaction question


Hi,

Do we really have to do all this in the name of reusability.  Can't you
change the way you code? 
Can't you overload/refactor a method and have the transaction
externalized.

Assume you have 

methodA
startTransaction();
     // do some business logic.
     callDAO.doSomething();
endTransaction();

Instead change it to

methodA [    // All that methodA is used is for now Transaction
Encapsulation and not anything
else.
    startTransaction()
    methodB
    endTransaction()
]

methodB [
    // do some business logic.
    callDAO.doSomething();
]

In a different service manager instead of calling the methodA and hence
having nested transactions, can't you call methodB instead.

Rgds

Prashanth Sukumaran.

 

--- "Barnett, Brian W." <brian.barnett@pearson.com> wrote:

> Niels,
> Thanks for the info. Maybe I am not totally understanding how your 
> modified code works, but is it meant to handle nested transactions?
> 
> If a transaction has already been started, then your modified code 
> will simply call invoke. I understand that. What happens when a nested

> transaction calls commitTransaction()? (Like doSomethingElse() calling
> doSomething() in the sample code below.) commitTransaction() gets 
> called twice in this example. I believe it will throw an exception.
> 
> What I was considering was to add a ThreadLocal transactionCounter 
> variable to DaoContext. start, commit and end transaction methods 
> might look something like this:
> 
>   public void startTransaction() {
>     transactionCounter++;          // <-- NEW LINE OF CODE
>     if (transactionCounter == 1) { // <-- NEW LINE OF CODE
>       if (state.get() != DaoTransactionState.ACTIVE) {
>         DaoTransaction trans = transactionManager.startTransaction();
>         transaction.set(trans);
>         state.set(DaoTransactionState.ACTIVE);
>         daoManager.addContextInTransaction(this);
>       }
>     }                              // <-- NEW LINE OF CODE
>   }
> 
>   public void commitTransaction() {
>     if (transactionCounter == 1) { // <-- NEW LINE OF CODE
>       DaoTransaction trans = (DaoTransaction) transaction.get();
>       if (state.get() == DaoTransactionState.ACTIVE) {
>         transactionManager.commitTransaction(trans);
>         state.set(DaoTransactionState.COMMITTED);
>       } else {
>         state.set(DaoTransactionState.INACTIVE);
>       }
>     }                              // <-- NEW LINE OF CODE
>   }
> 
>   public void endTransaction() {
>     try {                            // <-- NEW LINE OF CODE
>       if (transactionCounter == 1) { // <-- NEW LINE OF CODE
>         DaoTransaction trans = (DaoTransaction) transaction.get();
>         if (state.get() == DaoTransactionState.ACTIVE) {
>           try {
>             transactionManager.rollbackTransaction(trans);
>           } finally {
>             state.set(DaoTransactionState.ROLLEDBACK);
>             transaction.set(null);
>           }
>         } else if (transactionCounter == 1) {
>           state.set(DaoTransactionState.INACTIVE);
>           transaction.set(null);
>         }
>       }                     // <-- NEW LINE OF CODE
>     } finally {             // <-- NEW LINE OF CODE
>       transactionCounter--; // <-- NEW LINE OF CODE
>     }                       // <-- NEW LINE OF CODE
>   }
> 
> The idea being that the transaction related logic only executes when 
> we are dealing with the first transaction bracket that was opened. I 
> haven't actually tried this out, but I think I will. Let me know if 
> you, or anyone else, sees any problems with this approach.
> 
> Thanks,
> Brian Barnett
> 
> -----Original Message-----
> From: Niels Beekman [mailto:n.beekman@wis.nl]
> Sent: Wednesday, August 17, 2005 3:00 PM
> To: user-java@ibatis.apache.org
> Subject: RE: Transaction question
> 
> 
> Hi,
> 
> I'm facing this exact same problem however in a somewhat different 
> context, see the following archived thread:
> 
> http://www.mail-archive.com/ibatis-user-java@incubator.apache.org/msg0
> 25
> 80.html
> 
> http://www.mail-archive.com/user-java@ibatis.apache.org/msg00036.html
> 
> I recently restarted my investigation into this problem and have tried

> some hacks in the iBATIS code, the changes were made in DaoProxy.java 
> (which proxies DAO-interfaces to provide transaction-semantics) and 
> DaoContext.java (which handles the transactions itself). Of course 
> this is rather messy, but I really do not like the SavePoint-support 
> mentioned in the thread above, I think it is rather a workaround than 
> a solution.
> 
> Anyway, my changes (totally unverified, without any guarantees) in 
> package
> com.ibatis.dao.engine.impl:
> 
> DaoContext.java, added isTransactionRunning():
> 
> public boolean isTransactionRunning() {
>   return transaction.get() != null;
> }
> 
> DaoProxy.java, modified invoke(): see attached file.
> 
> This seems to work pretty good in my case, however further 
> investigation is required.
> 
> I hope the iBATIS devteam can comment on my solution, whether you 
> think it will work, or when you believe it really sucks :)
> 
> Greetings,
> 
> Niels
> 
> -----Original Message-----
> From: Barnett, Brian W. [mailto:brian.barnett@pearson.com]
> Sent: woensdag 17 augustus 2005 22:00
> To: 'user-java@ibatis.apache.org'
> Subject: Transaction question
> 
> What are some good options to deal with the following:
> 
> ServiceClass1
> public void doSomething() {
> 	try {
> 		daoManager.startTransaction();
> 		// Write some stuff to a database
> 		daoManager.commitTransaction();
> 	} catch (Exception e) {
> 		throw e;
> 	} finally {
> 		daoManager.endTransaction();
> 	}
> }
> 
> ServiceClass2
> public void doSomethingElse() {
> 	try {
> 		daoManager.startTransaction();
> 		ServiceClass1 sc1 = new ServiceClass1();
> 		sc1.doSomething();
> 		// Write some stuff to a database
> 		daoManager.commitTransaction();
> 	} catch (Exception e) {
> 		throw e;
> 	} finally {
> 		daoManager.endTransaction();
> 	}
> }
> 
> The doSomethingElse() method will fail because startTransaction() gets

> called twice. I need a good way to be able to re-use business logic 
> methods in different, or the same, service layer classes.
> 
> One thing I have done in the past is create a whole new layer, 
> essentially a service delegate, where I have moved all the transaction

> logic to. I didn't like that too much because it was just a huge 
> proliferation of methods just to solve the "no nested transaction" 
> problem.
> 
> I have also passed flags into methods to indicate if a transaction has

> already been started, but passing flags is messy to say the least.
> 
> Any great ideas out there?
> 
> TIA,
> Brian Barnett
> 
> **********************************************************************
> **
> **** 
> This email may contain confidential material. 
> If you were not an intended recipient, 
> Please notify the sender and delete all copies. 
> We may monitor email to and from our network. 
>
************************************************************************
> ****
> 
> **********************************************************************
> ******
> This email may contain confidential material. 
> If you were not an intended recipient, 
> Please notify the sender and delete all copies. 
> We may monitor email to and from our network. 
>
************************************************************************
****
> 



		
____________________________________________________
Start your day with Yahoo! - make it your home page 
http://www.yahoo.com/r/hs 
 

************************************************************************
**** 
This email may contain confidential material. 
If you were not an intended recipient, 
Please notify the sender and delete all copies. 
We may monitor email to and from our network. 
************************************************************************
****


Mime
View raw message