Once again I seem to have found a solution shortly after asking the question...

On 08/04/2008, Alistair Young <[EMAIL PROTECTED]> wrote:
> [ ... snip ... ]
>
>        // start a transaction
>        // [iBATIS starts a new JTA transaction...?]
>        sqlMapClient.startTransaction();
>
>        // ... do some database processing ...
>
>        // start an inner transaction
>        // [iBATIS joins the existing JTA transaction...?]
>        sqlMapClient.startTransaction();
>
>        // ... do some more database processing ...
>
>        // abandon the inner transaction
>        // [iBATIS issues setRollbackOnly on JTA transaction...?]
>        sqlMapClient.endTransaction();
>
>        // commit the outer transaction
>        // [iBATIS issues commit on JTA transaction...?]
>        sqlMapClient.commitTransaction();
>
>  with the final result that the database is unchanged.  However,
>  instead, I get an exception on my second call to startTransaction()
>  complaining that a transaction is already started.
>
>  [ ... snip ... ]

After a bit of experimentation, I think that I need to explicitly
start the JTA transaction outside of the iBATIS transactions.  The
following does what I'd expected:

       // start a JTA transaction
       Context ctx = new InitialContext();
       UserTransaction ut =
(UserTransaction)ctx.lookup("java:comp/UserTransaction");
       ut.begin();

       // start an iBATIS transaction
       // [iBATIS joins the JTA transaction]
       sqlMapClient.startTransaction();

       // ... do some database processing ...

       // commit the iBATIS transaction
       // [iBATIS does not actually commit to the db]
       sqlMapClient.commitTransaction();

       // start another iBATIS transaction
       // [iBATIS joins the JTA transaction]
       sqlMapClient.startTransaction();

       // ... do some more database processing ...

       // abandon the iBATIS transaction
       // [iBATIS issues setRollbackOnly on JTA transaction]
       sqlMapClient.endTransaction();

       // commit the JTA transaction
       try {
              ut.commit();
       } catch (RollbackException x) {
              // will be raised because the commit did
              // not take place (since the second iBATIS
              // transaction was cancelled)
       }

Please feel free to suggest a better way, if one should exist!


Alistair.

Reply via email to