Adam,

In some I can agree and have done exactly what you are talking about with
aspectj.  Every approach has its pluses and minuses so I would say go with
what makes sense for your application.

Ron


On 8/11/09 8:28 PM, "Adam B" <[email protected]> wrote:

> That's pretty cool, Andy.  Thanks.  Having virtually zero experience with
> AspectJ I'm pleasantly surprised by it's apparent power.  From my perspective,
> as a noob, this actually looks more understandable than any of the Spring
> examples I've seen thus far.  Then again, I find myself gravitating towards
> DIY solutions as opposed to big frameworks.
> 
> Andy Clement wrote:
>> and i'll just chip in.  I do think AspectJ can help with your logic - but
>> Spring may be a good answer too.
>>  
>>> > 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.
>>  
>> something like that is simply:
>>  
>> before(): handler(C_DoesNotExist) {...}
>>  
>> to choose a particular catch block you also throw in a cflow(...) or a
>> withincode(...)
>>  
>> but just exploring some options, here are some possibilities:
>>  
>> // remove all the 'stuff' from doOperationX
>> around(): execution(@Transactional * *(..)) {
>>  
>>     connection = get_connection()
>>     connection.start_transaction()
>>     try {
>>       proceed();
>>  
>>       connection.commit();
>>     } finally {
>>         connection.end_transaction()  //rolls back uncommitted
>>         connection.close()
>>     }
>> }
>> 
>> // if calling updateC from updateB and it fails, just ignore it
>> 
>> around(): call(* updateC(..)) && withincode(* updateB(..)) {
>>   try {
>>     proceed();
>>   } catch (C_DoesNotExist) {
>>     // ignore
>>   }
>> }
>> 
>>   
>>  
>> @Transactional function doOperationX()
>> {
>> 
>>         updateA(connection)
>>         updateB(connection)
>> }
>> 
>> 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 <http://c.id/>  FROM c INNER
>> JOIN b ON ...")
>>     if (result.next())
>> 
>>         connection.execute("UPDATE c SET ...")
>>     else
>>         throw C_DoesNotExist()
>> }
>>  
>> Andy
>>  
>>  
>>  
>> 2009/8/11 Adam Bennett <[email protected]>
>>  
>>>  
>>> 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]
>>>> <http://[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 <http://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] <http://[email protected]>
>>>>>>  https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>>>>>  
>>>>>>  
>>>>>>   
>>>>>>  
>>>>>  
>>>>>  
>>>>>  
>>>>> 
>>>>> _______________________________________________
>>>>> aspectj-users mailing list
>>>>>  [email protected] <http://[email protected]>
>>>>>  https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>>>>  
>>>>  
>>>>  
>>>>  
>>>>  
>>>> Ron DiFrango            
>>>>  Manager and Architect  |  CapTech Ventures
>>>> (804) 855-9196-6308  |  [email protected]
>>>> <http://[email protected]>
>>>>   
>>>>  
>>>  
>>>  
>>>  
>>> 
>>>  
>>> Videx Inc. 1105 N. E. Circle Blvd. Corvallis OR 97330 (541) 758-0521
>>> CONFIDENTIAL COMMUNICATION: The email message and any attachments are intend
>>> ed only for the addressee.  They may be privileged, confidential, and protec
>>> ted from disclosure. If you are not the intended recipient, any disseminatio
>>> n, distribution, or copying is expressly prohibited.  If you received this e
>>> mail message in error, please notify the sender immediately by replying to t
>>> his 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
>>   
> 
> 
> 
> 
> 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

Reply via email to