Thanks for the tips, Jeff. It appears, however, that although the iBATIS "startTransaction" will not start another transaction if a JTA transaction exists, it will still thrown an exception. (I'd assumed - incorrectly - that all of the transaction handling would be handed off to JTA).
Anyway, I seem to be on the right track now! Cheers, Alistair. On 08/04/2008, 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. > > > >