Current development on JAMWiki is primarily focused on maintenance rather than new features due to a lack of developer availability. If you are interested in working on JAMWiki please join the jamwiki-devel mailing list.

Tech:Transactions

ktip.png This page (and all pages in the Tech: namespace) is a developer discussion about a feature that is either proposed for inclusion in JAMWiki or one that has already been implemented. This page is NOT documentation of JAMWiki functionality - for a list of documentation, see Category:JAMWiki.
Status of this feature: IMPLEMENTED. This feature was included with JAMWiki 0.6.6.
Contents

Description[edit]

Implement a minor improvement to the Transaction handling code within the jamwiki-web code, making use of the Transaction support found in the Spring Framework.

The rationale for the change is that prior to version 0.6.5 there existed a subtle bug whereby multiple independant transactions were created when setting up the database, which would cause a deadlock scenario on some databases. The "inner" transaction should not have been created; but database work was invoked from within parser generated code which was unaware of the already existing "outer" transaction and did not participate in that transaction as it should have.

Although the particular bug was corrected by changing the flow of the code within that service method, improvement can be made to the transaction handling to prevent such a bug from being accidentally re-introduced.

My suggestion is to leverage the solid transaction support of the Spring Framework for demarcating transactions, while retaining JDK 1.3/1.4 compatibility and keeping to a minimum the scope of code changes.

Author(s)[edit]

Status[edit]

Code is ready to be checked-in to the subversion repository.

Implementation Details[edit]

The Spring Framework provides support for 2 styles of Transactions; programmatic and declarative. The Spring documentation advocates declarative transactions; however this is not appropriate for JAMWiki as the service layer of the application is not "wired up" via the Spring application context (instead relying on static methods of helper classes).

When using programmatic transaction handling with Spring, it is often recommended to use the TransactionTemplate, but I have chosen against this as many existing method signature throw Exception, whereas using TransactionTemplate only RuntimeExceptions can be used.

So the current practice of try / catch / finally blocks must be retained. Code which needs to run within a transaction would like the following: -

TransactionStatus status = WikiDatabase.startTransaction();
try {
    Connection conn = WikiDatabase.getConnection();     
    // start code to be executed within the transaction
    ...
    // end of code to be executed within the transaction
} catch (Exception e) {
    WikiDatabase.rollbackOnException(status, e);
    throw e;
} catch (Error err) {
    WikiDatabase.rollbackOnException(status, err);
    throw err;
}
WikiDatabase.commit(status);

Although this service layer code shown is not substantially different from the current implementation, it does have an advantage that the connections returned from the WikiDatabase.getConnection() method automatically participate in any active transaction on the current thread of execution, because of the "behind the scenes" use of Spring's DataSourceTransactionManager and DataSourceUtils classes to make the database code fully "transactionally aware".

Comments[edit]