Allowing Subtransactions
You may have noticed that we have the following startup config parameter (in jta.properties):
com.atomikos.icatch.allow_subtransactions=true
Even if you don't have it in your config, it still exists as a default.
What It Does
What does this do, and why would you ever want to disable it? When enabled, you can have uses cases like this one:
UserTransactionManager utm = new UserTransactionManager(); tx1 = utm.begin(); tx2 = utm.begin(); //exception in tx2 tx2.rollback(); //try alternatives to tx2's logic tx1.commit();
In particular, you can start a transaction tx2 (a "subtransaction") inside an existing transaction tx1 (the "parent") and have tx2 rollback independently. When that happens, tx1 can still try some alternative logic and commit. This allows more advanced exception handling inside tx1.
What happens if tx2 commits instead? Like this:
UserTransactionManager utm = new UserTransactionManager(); tx1 = utm.begin(); tx2 = utm.begin(); //exception in tx2 tx2.commit(); tx1.commit();
In this case, the commit of tx2 essentially marks its resource accesses for inclusion in the final commit of tx1. In other words, commit of a sub transaction does not do anything special besides delaying the commit to the parent.
When Disable This?
There are 2 cases when subtransactions may not be ideal:
- If tx2 needs to see the updates of tx1 - this may or may not block depending on the case DBMS drivers and the use case.
- If your application is buggy and leaves tx1 pending - so it is reuse for a later request if you have thread pooling. This can give hard-to-find issues where later requests are really executed inside the scope of a previous transaction.