Transactions

This article explains how transactions are managed with the help of RS Library, especially with the Data Base Classes.

Overview

If you are unfamiliar with transactions, it is recommendend to read this article. It explains what transactions are respective to data persistence.

The default implementation uses JOTM as the underlying JTA Transaction Manager. If you require another Transaction Manager, you can do so by overriding AbstractDaoFactory.createTransactionManager() or AbstractDaoFactory.getTransactionManager().

Transactions with RS Library are bound to threads. That means that a transaction cannot span more than one thread. Each thread requires its own transaction. The implementation in AbstractDataFactory uses a TransactionContext as helper object. This context enables “nested” transactions. However, these are not real nested transactions. They are just virtual, implemented by a simple counter that increases with each begin() call, and decreases with each commit()/rollback() call. The implemented strategy enables you to reuse your application code at various levels without taking into consideration what context you are in. If you require a transaction for your method, enclose it in appropriate transaction demarcation.

Transaction Calls

Transactions are demarcated by calls to

1
2
// Start the transaction
factory.begin();

You should be aware that all methods that require interactions with databases, such as findBy(), create(), save() and delete() require an active transaction and will fail when there is no such transaction.

The transaction is successfully finalized when you call:

1
2
// Finalize the transaction
factory.commit();

If you want to abort your transaction, you need to call:

1
2
// Abort the transaction
factory.rollback();

Transaction Code Template

Use the following template for all your transactional code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
   try {
      // Start the transaction
      factory.begin();
 
      // Your transactional work
      ...
 
      // Commit the transaction
      factory.commit();
   } catch (Throwable t) {
      log.error("My error message", t);
      // Rollback any changes
      ...
      try {
         factory.rollback();
      } catch (Throwable t2) {
         log.error("Rollback failed", t2);
      }
   }

The first instruction is always the start of the transaction (line 3). It is, like all other code, surrounded in a try/catch block. Do not write any code between lines 1 and 3! This could result in a rollback() call in line 15 without begin() called in line 3.

Also, your last instruction within the block shall be commit() as code executed afterwards could result in a rollback() outside of the transaction. If you have additional work to do, put it either before commit() or after the try/catch block.

Please notice also the try/catch block around rollback() (lines 14-18). This will ensure that you exit the outer try/catch block properly.

Transaction Debugging

The Data Base Classes deliver an easy method to trace your transaction calls. You either directly call setDebugTransactions(true) or set the system property transaction.debug. This will log each and every begin(), commit() and rollback(). If you enable transaction.trace (or call setTraceTransactions(true)) then the log will also contain the stacktrace of these calls so you can identify who triggered a transaction demarcation.

JOTM

JOTM is a dependency of the Data Base Classes. You can access JOTM by JotmSupport class. It will start JOTM automatically when you require a transaction or ask for the Transaction Manager. As described before, you can use other Transaction Managers. Overriding AbstractDaoFactory.getTransactionManager() is recommended when your Transaction Manager is created independently. If you want Data Base Classes have the Transaction Manager created, you will need to override AbstractDaoFactory.createTransactionManager().

Hibernate Configuration

The following short snippet demonstrates how to configure Hibernate with JOTM as delivered by the RS Library:

1
2
3
4
5
6
7
8
9
10
11
12
13
<hibernate-configuration>
   <session-factory>
      <!-- How to find the Transaction -->
      <property name="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</property>
 
      <!-- How to produce transaction -->
      <property name="hibernate.transaction.jta.platform">rs.data.hibernate.util.JOTMJtaPlatform</property>
 
      <!-- Session context with JTA -->
      <property name="current_session_context_class">jta</property>
      ...
   </session-factory>
</hibernate-configuration>

One Response to “Transactions”

  1. American Steroids Online Says:

    […] with Bitcoins Buy American Steroids Online with Bitcoins Buy American Steroids Online with Bitcoins Buy American Steroids Online with Bitcoins Buy American Steroids Online with Bitcoins Buy American Steroids Online with Bitcoins Buy American […]

Leave a Reply