Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Database transactions and exceptions don t mix! (can AspectJ help?)

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:rdifrango@xxxxxxxxxxxxxxxxxxx]
To: aspectj-users@xxxxxxxxxxx
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" <tahir@xxxxxxxxxxxxxxxxxxx> 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
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users


  



_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Ron DiFrango            
Manager and Architect  |  CapTech Ventures
(804) 855-9196-6308  |  rdifrango@xxxxxxxxxxxxxxxxxxx




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

Back to the top