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
