Transaction Propagation
During application development there are situations when a transaction started in one method should be propagated to other method.
Lets suppose we have 2 methods.
public void method1() {
database.begin();
try {
method2();
database.commit();
} catch(Exception e) {
database.rollback();
}
}
public void method2() {
database.begin();
try {
database.commit();
} catch(Exception e) {
database.rollback();
}
}
As you can see transaction is started in first method and then new one is started in second method. So how these transactions should interact with each other. Prior 1.7-rc2 first transaction was rolled back and second was started so were risk that all changes will be lost.
Since 1.7-rc2 we start nested transaction as part of outer transaction. What does it mean on practice?
Lets consider example above we may have two possible cases here:
First case:
- begin outer transaction.
- begin nested transaction.
- commit nested transaction.
- commit outer transaction.
When nested transaction is started all changes of outer transaction are visible in nested transaction and then when nested transaction is committed changes are done in nested transaction are not committed they will be committed at the moment when outer transaction will be committed.
Second case:
- begin outer transaction.
- begin nested transaction.
- rollback nested transaction.
- commit outer transaction.
When nested transaction is rolled back, changes are done in nested transaction are not rolled back. But when we commit outer transaction all changes will be rolled back and ORollbackException will be thrown.
So what instances of database should we use to get advantage of transaction propagation feature:
- The same instance of database should be used between methods.
- Database pool can be used, in such case all methods which asks for db connection in same thread will have the same the same database instance.