With Spring transactions, there is no need to commit and/or rollback even
upon exception.  The only trick is defining the entry point to start the
transaction and Spring takes care of the rest.


On 8/11/09 3:49 PM, "Adam Bennett" <[email protected]> wrote:

> ORM would probably be too much change at once - much of our code base is very
> procedural.  We might consider Spring because it sounds like it could be
> refactored in incrementally.  Yet I fear that even with Spring it is still the
> programmers responsibility write explicit rollback logic when catching
> exceptions (I need to read up on Spring though).
> 
> Can AspectJ be used somehow to automatically install a hook inside the
> catch(C_DoesNotExist)  block?  If so that would let me make the rollback
> implicit.
> 
> 
>> 
>> From: Ron Difrango [mailto:[email protected]]
>> To: [email protected]
>> Sent: Tue, 11 Aug 2009 07:01:08 -0700
>> Subject: Re: [aspectj-users] Database transactions and exceptions don t mix!
>> (can AspectJ help?)
>> 
>> My initial reaction to this, is why don¹t you use either an ORM framework or
>> Spring to help you manage the transactions?
>> 
>> 
>> On 8/10/09 11:39 PM, "Tahir Akhtar" <[email protected]> wrote:
>> 
>>> You might want to read : InfoQ: Java Transaction Design Strategies
>>> <http://www.infoq.com/minibooks/JTDS>
>>> http://www.infoq.com/minibooks/JTDS
>>> 
>>> Adam Bennett wrote:
>>>>  
>>>> Lately I've been trying to improve how our web application employs
>>>> transactions (we don't use them enough). While doing this I became aware of
>>>> this rather general problem. It seems as though database transactions
>>>> cannot be mixed with exceptions unless great vigilance is practiced.  I'm
>>>> wondering if AspectJ can help me in some way.
>>>> 
>>>> Consider this pseudo code:
>>>> 
>>>> 
>>>> function doOperationX()
>>>> {
>>>>     connection = get_connection()
>>>>     connection.start_transaction()
>>>>     try
>>>>     {
>>>>         updateA(connection)
>>>> 
>>>>         try
>>>>         {
>>>>             updateB(connection)
>>>>         }
>>>>         catch (C_DoesNotExist)
>>>>         {
>>>>             //ignore (non fatal)
>>>>         }
>>>> 
>>>>         connection.commit()
>>>>     }
>>>>     finally
>>>>     {
>>>>         connection.end_transaction()  //rolls back uncommitted
>>>>         connection.close()
>>>>     }
>>>> }
>>>> 
>>>> function updateA(connection)
>>>> {
>>>>     connection.execute("UPDATE a SET ...")
>>>> }
>>>> 
>>>> function updateB(connection)
>>>> {
>>>>     connection.execute("UPDATE b SET ...")
>>>>     updateC(connection)
>>>> }
>>>> 
>>>> function updateC(connection)
>>>> {
>>>>     result = connection.execute("SELECT c.id FROM c INNER JOIN b ON ...")
>>>>     if (result.next())
>>>>         connection.execute("UPDATE c SET ...")
>>>>     else
>>>>         throw C_DoesNotExist()
>>>> }
>>>> 
>>>> 
>>>> 
>>>> Don't study the pseudo SQL too closely, the problem isn't there. Read the
>>>> code like this:
>>>> 
>>>> 1) operationX requires updating of A and, optionally, B.
>>>> 2) Internally, updating B always requires that C also be updated. All or
>>>> nothing.
>>>> 3) Sometimes, C cannot be updated because the database is not in the proper
>>>> state at this time. (Not an invalid state, mind you)
>>>> 4) operationX knows that C might not be updatable, so it catches the
>>>> exception and ignores it.
>>>> 
>>>> The problem is:
>>>> 
>>>>    updateB() leaves the database in an inconsistent state if an exception
>>>> is thrown
>>>>    out of updateC().  The inconsistency is that table B has been updated
>>>> but D has
>>>>    not been updated accordingly.
>>>> 
>>>> Yet, it's only a problem because operationX caught the exception. Had it
>>>> let the exception continue up, the finally block would have rolled back the
>>>> entire transaction quite nicely.
>>>> 
>>>> How can I avoid this problem? The only proper solution that I can see is a
>>>> prolific use of transaction checkpoints (aka savepoints) so that a partial
>>>> rollback can occur if needed:
>>>> 
>>>> 
>>>> function updateB(connection)
>>>> {
>>>>     success = false
>>>>     savepoint = connection.setSavepoint()
>>>>     try
>>>>     {
>>>>         connection.execute("UPDATE b SET ...")
>>>>         updateD(connection)
>>>>         success = true
>>>>     }
>>>>     finally
>>>>     {
>>>>         if (not success)
>>>>             connection.rollback(savepoint)
>>>>     }
>>>> }
>>>> 
>>>> 
>>>> 
>>>> But this hurts performance considerably and requires programmer vigilance
>>>> and lots of extra code! The programmer must remember that:
>>>> 
>>>>   **If your function does more than one update it MUST use a savepoint!**
>>>> 
>>>> That's tough pill to swallow (for me). I try to avoid programming models
>>>> that require programmer vigilance. All it takes is one groggy Monday...
>>>> 
>>>> What do you think? Am I missing a better solution?  Can AspectJ help?
>>>> 
>>>> Videx Inc. 1105 N. E. Circle Blvd. Corvallis OR 97330 (541) 758-0521
>>>> CONFIDENTIAL COMMUNICATION: The email message and any attachments are
>>>> intended only for the addressee.  They may be privileged, confidential, and
>>>> protected from disclosure. If you are not the intended recipient, any
>>>> dissemination, distribution, or copying is expressly prohibited.  If you
>>>> received this email message in error, please notify the sender immediately
>>>> by replying to this e-mail message or by telephone
>>>> 
>>>> _______________________________________________
>>>> aspectj-users mailing list
>>>> [email protected]
>>>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>>> 
>>>> 
>>>>   
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> aspectj-users mailing list
>>> [email protected]
>>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>> 
>> Ron DiFrango    
>> Manager and Architect  |  CapTech Ventures
>> (804) 855-9196-6308  |  [email protected]
> 
> 
> 
> Videx Inc. 1105 N. E. Circle Blvd. Corvallis OR 97330 (541) 758-0521
> CONFIDENTIAL COMMUNICATION: The email message and any attachments are intended
> only for the addressee.  They may be privileged, confidential, and protected
> from disclosure. If you are not the intended recipient, any dissemination,
> distribution, or copying is expressly prohibited.  If you received this email
> message in error, please notify the sender immediately by replying to this
> e-mail message or by telephone
> 
> 
> _______________________________________________
> aspectj-users mailing list
> [email protected]
> https://dev.eclipse.org/mailman/listinfo/aspectj-users

Ron DiFrango       
Manager and Architect  |  CapTech Ventures
(804) 855-9196-6308  |  [email protected]

_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to