Package net.sourceforge.hivetranse.transaction

This is the main package for generic transaction handling under HiveMind.

See:
          Description

Interface Summary
TransactionEventListener Listener interface for TransactionService-related events.
TransactionService General interface for a Transaction managing service.
 

Class Summary
AbstractTransactionService Base class for every actual implementation of TransactionService.
AbstractTransactionService.Context  
AbstractTransactionService.TransactionObject  
RollbackExceptionContribution Represents a configuration parameter to the Transaction Interceptor configured for a service.
TransactionContribution Represents a configuration parameter to the Transaction Interceptor configured for a service.
TransactionInterceptorFactory This service creates service interceptors that manage transactions.
TransactionSettingsContribution  
 

Enum Summary
TransactionDemarcation Defines the transaction demarcation for an executable scope (method of a service).
 

Exception Summary
ForbiddenTransactionException Thrown by TransactionService implementations when a transaction currently exists but the current context does not allow any.
MandatoryTransactionException Thrown by TransactionService implementations when a transaction is currently required but does not exist in the current context.
TransactionException Thrown by TransactionService implementations when transaction management fails.
 

Package net.sourceforge.hivetranse.transaction Description

This is the main package for generic transaction handling under HiveMind.

It defines the necessary interfaces and classes for dealing generally with transactions under HiveMind.
The core of HiveMind-Transactions handling is the TransactionService. The implementations of this service handle the real transactions in a thread-safe manner.

Threads and Transaction Context

In a multi-threaded application (such as a Web application), each thread has its own private Transaction context, which means that two threads can never share the same transaction.

Transaction Demarcations

In addition to the transaction-per-thread point, it is possible in one given thread to have several different transaction scopes changing while service methods are being called.
Each scope is determined by a transaction demarcation property that defines how transactions should be handled inside this scope.
A new scope generally begins when a method of a service is called, and ends when that method returns. This method may, in turn, call a method of another service with a new scope.
The various demarcations that exist are the same as defined in the EJB specification from Sun.

Automatic Transaction Handling

Transaction scopes can be started and ended automatically by adding a TransactionInterceptor to the service that needs transaction management. It is possible to configure the Transaction demarcation for any method of the service that is intercepted. Hence, some methods may have no Transaction context during their execution, while others may force the existence of one transaction.
It is important to note that, as in EJB, if a method of a service calls another methods of the same service directly (i.e. through this, then the interceptors are never called and hence specific demarcation to the called method does not apply.
If necessary, it would still be possible to configure the service to be injected a reference to itself (HiveMind would then inject a proxy that will ensure that interceptors are called). However this is not a very good practice.

Transactions and Exceptions

The implementation of automatic transaction handling offers more flexibility than the EJB specification regarding the handling of exceptions that occur.
It is possible to define, for each service, which exceptions should force a rollback of the current transaction, and which exceptions should not impact the current transaction.

Manual Transaction Handling

It is also possible to manage transactions programmatically in the code of a service. For that, the service must be injected the TransactionService and then call its methods directly. It is important to make sure that a transaction scope that is open programmatically by a service will always be ended by this service (at least before the end of execution of the current thread, but it is strongly advises that the method that begins a transaction scope ends it before returning, even in case of an exception).
Note that generally, manual transaction handling is not useful and automatic handling is much better and easier to develop with.

Creating a new implementation of TransactionService

There are currently several implementations of TransactionService. If needed, the easiest way to implement a new one is to derive from AbstractTransactionService and implement the few abstract methods; this way, you do not have to deal with the management of transaction scope switching and demarcation handling... You just have to write the code that creates a new transaction and that later commits or rollback that transaction.

TransactionInterceptor usage

Whenever one of your services need to be in a specific transaction scope, then it should be intercepted by TransactionInterceptor. The configuration for the interceptor includes the transaction demarcation to be used for the service (or for individual methods of the service), and the way to deal with transaction commit or rollback when exceptions are thrown by the service.
The following is an excerpt of such a configuration:
        <interceptor service-id="hivetranse.core.TransactionInterceptor">
                <method pattern="*" demarcation="Required"/>
                <exception name="java.lang.Throwable" rollback="true"/>
        </interceptor>
In the example above, the configuration means that a call to any method of the service will use the Required transaction demarcation, and that any exception thrown will rollback the current transaction (here, this is different from EJB behavior where only unchecked exceptions would rollback the current transaction).
It is possible to define default configuration for transaction demarcation and exception handling, used y default for the whole application. Of course, it is still possible to override these defaults in each <interceptor> declaration.
An example of default declaration is given below:
        <contribution configuration-id="hivetranse.core.TransactionDefaults">
                <defaults>
                        <exception name="java.lang.Exception" rollback="false"/>
                        <exception name="java.lang.Throwable" rollback="true"/>
                        <method pattern="*" demarcation="Never"/>
                </defaults>
        </contribution>
This default configuration mimics the way an EJB container works, except for the fact that EJB has no "default" transaction demarcation and obliges you to define it for your beans.
If your service requires the default transaction handling, then you just have to declare the interceptor with no configuration at all:
        <interceptor service-id="hivetranse.core.TransactionInterceptor"/>
Please not that if you do not define a Transaction Interceptor for a service, then the kind of transaction demarcation for this service will be the same as was existing in for the caller of that service.
In case no transaction demarcation has been defined in the whole calling chain, then you can consider this to be equivalent to NotSupported demarcation, ie no transaction is available to your service.

Differences with EJB

The following differences between hivetranse.core and EJB must be noted: