Thanks for the suggestion, Clinton - I shall have an experiment with
that approach. (Very handy book too, by the way!)
Alistair.
On 08/04/2008, Clinton Begin <[EMAIL PROTECTED]> wrote:
> I usually suggest just using the EXTERNAL transaction manager and let your
> container manage the transaction entirely. I'm pretty sure this works well
> for most people.
>
> Clinton
>
>
> On Tue, Apr 8, 2008 at 10:18 AM, Jeff Butler <[EMAIL PROTECTED]> wrote:
>
> >
> > iBATIS does not support nested transactions. Take a look at the class
> com.ibatis.sqlmap.engine.transaction.jta.JtaTransaction to
> see what's going on.
> >
> > If a JTA transaction already exists...
> >
> > 1. The iBATIS "startTransaction" will not start another transaction
> > 2. The iBATIS commit does nothing
> > 3. The iBATIS rollback marks the transaction for rollback, but does not
> rollback itself
> >
> > When there are externally managed transactions, the iBATIS rollback will
> mark the external transaction for rollback, but the other two methods do,
> essentially, nothing.
> >
> > Jeff Butler
> >
> >
> >
> >
> >
> > On Tue, Apr 8, 2008 at 9:44 AM, Alistair Young
> <[EMAIL PROTECTED]> wrote:
> >
> > > 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.
> > >
> >
> >
>
>