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.
> >
>
>

Reply via email to