com.sap.transaction

Class TxManager

java.lang.Object
  extended by com.sap.transaction.TxManager

public final class TxManager
extends Object

The TxManager class provides a set of static methods that allow applications to handle JTA transactions in a convenient and controlled way. The implementation of the TxManager methods is completely based on the JTA transaction API as defined by the J2EE standard. So, this class is simply a convenience facade to the JTA implementation provided by the J2EE server.

The transaction control methods provided by this class essentially emulate the two basic transaction control properties of EJB methods: required and requiresNew . The required attribute means that the EJB method needs to be executed under transaction control. If there is already an open JTA transaction associated with the current thread, then this one will be "joined". Otherwise, if no open JTA transaction exists, a new one will be started. Contrary to this, the requiresNew attribute indicates that a new and independent JTA transaction must be started to execute the EJB method, even if there is already an open JTA transaction associated with the current thread. Because the JTA concept does not support nested transactions, there can be only one JTA transaction associated with a thread at one time. This means, that an open transaction must be suspended before a new transaction can be started. The suspended transaction is resumed after the new transaction has been completed (either committed or rolled back).

The TxManager offers an analogous transaction control mechanism as the required/requiresNew attributes as a programmatic API for non-EJB components. But in contrast to the descriptive specification of transaction attributes for EJB methods, which are implictly controlled by the EJB container, explicit transaction demarcation involves the risk that an error in control flow can cause mismatches between the calls that start a transaction and those that complete a transaction. Therefore, the TxManager enforces the balancing of transaction demarcation calls by returning a transaction ticket (an instance of the class TxTicketImpl) when a transaction is started (either by a call of required()or requiresNew()method). This ticket uniquely identifies the "transaction level" and it must be passed as an argument to the respective calls that complete the transaction on this level ( #commitLevel(TxTicket)and #leaveLevel(TxTicket)).

Note that the "transaction levels" identified by transaction tickets does not necessarily correspond to as many levels of JTA transactions. Because the required()method simply joins an already open JTA transaction, there might be several "transaction levels" in the TxManager sense referring to the same JTA transaction.

In order to support applications with high performance requirements, which may have the need to collect modifications on persistent objects first in a cache (instead of writing them directly to the database) and then write them more efficiently (for example using batch operations) at the very end of a JTA transaction, the TxManager provides a method registerSynchronization(String, javax.transaction.Synchronization) to register application specific synchronization objects with a transaction. The javax.transaction.Synchronization interface has two callback methods: beforeCompletion() and afterCompletion(). The beforeCompletion() methods are called by the TxManager immediately before the JTA transaction commits, whereas the afterCompletion() methods are called when the commit processing has been finished. It is important to note, that the synchronization objects are registered with the current JTA transaction and not with the transaction levels controlled by the TxManager. This means, that a call of method commitLevel() does not necessarily cause the invocation of the synchronization callbacks, but only if the current JTA transaction has been started on this transaction level. In contrast to the corresponding method in the javax.transaction.Transaction interface, the TxManager.registerSynchronization() method requires an synchronization identifier as an additional argument. This synchronization identifier is used by the TxManager to invoke the synchronization callbacks in a well-defined order, thus reducing the likelyhood of deadlocks.

Method getRegisteredSynchronization(String)can be used to retrieve a registered synchronization object from the current JTA transaction. This method might be useful, if an application wants to register a persistence manager as a synchronization object with the current JTA transaction. By this, the application has always access to its persistent manager while the transaction is running.

If an application encounters an error situation that requires the current JTA transaction to be rolled back, then it should call method setRollbackOnly()which marks the transaction for rollback only. Marking a JTA transaction for rollback only means, that later on, when the transaction is about to be committed, the commit will be turned into a rollback.

Here is a code fragment that demonstrates a typical use-case of the TxManager methods:






        import com.sap.engine.services.ts.transaction.*;



        public void aDatabaseAccessMethod(...) {
            TransactionTicket ticket = null;
            try {
                // join the current JTA transaction or start a new one if no
                // transaction exists
                ticket = TxManager.required();
                ...
                if (someConsistencyCheckFailed()) {
                    // mark the current transaction for rollback only
                    TxManager.setRollbackOnly();
                }
                ...
                // if everything is fine, commit the database modifications on
                // this transaction level; note, that this might be a noop here, if
                // the previous call of required() has not started its own JTA
                // transaction but only joined an existing one
                TxManager.commitLevel(ticket);

            } catch (TxRollbackException e) {
                // The commit has turned into a rollback; maybe there are some
                // cleanups necessary, otherwise you can omit this catch block
                ...

            } catch (TxException e) {
                // The transaction manager has encountered an unexpected error
                // situation; turn this into an according application exception
                throw new ApplicationException(...);

            } finally {
                // Complete and leave the current transaction level; if the
                // commitLevel() operation has not been executed because some
                // application error ocurred, then the virtual transaction will be
                // rolled back implicitly by the leaveLevel() method (either by
                // directly executing a rollback operation, if the transaction was
                // started on this level, or indirectly by marking the current
                // transaction for rollback only).
                TxManager.leaveLevel(ticket);
            }
        }







 

Some remarks on possible error situations:

See Also:
TxTicketImpl

Method Summary
static void commitLevel(TransactionTicket txticket)
          Commmits the transaction level associated with the given transaction ticket.
static Synchronization getRegisteredSynchronization(String SID)
          Gets the Synchronization object previously registered with the current transaction under the given synchronization id (SID).
static boolean isTxActive()
          Checks whether the transaction associated with the current thread is active.
static boolean isTxMarkedRollback()
          Checks whether the transaction associated with the current thread is marked for rollback.
static void leaveLevel(TransactionTicket ticket)
          Finishes and leaves the transaction level associated with the given transaction ticket.
static void registerSynchronization(String SID, Synchronization sync)
          Registers the given Synchronization object with the current transaction.
static TransactionTicket required()
          Requires a new JTA transaction to be started or an already open transaction to be joined.
static TransactionTicket requiresNew()
          Requires a new transaction to be started.
static void setRollbackOnly()
          Marks the current JTA transaction for rollback.
static void setTxManagerImpl(ITxManager mgr)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

setTxManagerImpl

public static void setTxManagerImpl(ITxManager mgr)

commitLevel

public static void commitLevel(TransactionTicket txticket)
                        throws TxException,
                               TxDemarcationException,
                               TxRollbackException
Commmits the transaction level associated with the given transaction ticket.

If no JTA transaction has been started on the this transaction level, then this method has no effect.

A TxRollbackException is thrown if the transaction was rolled back rather than committed.

Parameters:
ticket - a transaction ticket.
Throws:
TxRollbackException - thrown to indicate that the transaction has been rolled back rather than committed.
TxDemarcationException - thrown if the belance of the transaction demarcation calls has been violated.
TxException - thrown if the transaction manager encounters an unexpected error situation.

getRegisteredSynchronization

public static Synchronization getRegisteredSynchronization(String SID)
                                                    throws TxException,
                                                           TxDemarcationException
Gets the Synchronization object previously registered with the current transaction under the given synchronization id (SID).

Parameters:
sid - a synchronization identifier
Returns:
the Synchronization object registered with the specified SID, null if no Synchronization object has been registered under the given SID.
Throws:
TxDemarcationException - thrown if no transaction is associated with the current thread.
TxException - thrown if the transaction manager encounters an unexpected error situation.

registerSynchronization

public static void registerSynchronization(String SID,
                                           Synchronization sync)
                                    throws TxException,
                                           TxDemarcationException,
                                           TxRollbackException,
                                           TxDuplicateOIDRegistrationException
Registers the given Synchronization object with the current transaction. The specified synchronization id (SID) is used to define an order on the registered synchronization objects, thus reducing the probability of database deadlocks.

Parameters:
sid - a synchronization identifier
sync - a Synchronization object implementing the beforeCompletion() and afterCompletion() callbacks.
Throws:
TxSynchronizationException - thrown if the given synchronization object conflicts with a another synchronization object that has already been registered under the same synchronization id before.
TxDemarcationException - thrown if no transaction is associated with the current thread.
TxRollbackException - thrown if the transaction associated with the current thread is marked for "rollback only".
TxException - thrown if the transaction manager encounters an unexpected error situation.
TxDuplicateOIDRegistrationException

required

public static TransactionTicket required()
                                  throws TxException,
                                         TxRollbackException
Requires a new JTA transaction to be started or an already open transaction to be joined. If there is already an open transaction associated with the current thread, this transaction is joined. Otherwise, if no transaction exists, a new transaction is started and associated with the current thread.

The method returns a transaction ticket as a unique identifier for this transaction level. Later on, this ticket has to be passed as an argument to the methods commitLevel() and leaveLevel(), in order to associate them with the transaction level opened by this call.

Returns:
a transaction ticket.
Throws:
TxException - thrown if the transaction manager encounters an unexpected error situation.
TxRollbackException - thrown if there is already a transaction associated with the current thread and this transaction is marked for rollback only, for example, as a result of a setRollbackOnly() call.

requiresNew

public static TransactionTicket requiresNew()
                                     throws TxException
Requires a new transaction to be started. If there is already an open transaction associated with the current thread, this transaction will be suspended and the new transaction will be associated with the thread. The suspended transaction will be resumed, when this transaction is completed (either committed or rolled back).

The method returns a transaction ticket as a unique identifier for this transaction level. Later on, this ticket has to be passed as an argument to the methods commitLevel() and leaveLevel(), in order to associate them with the transaction level opened by this call.

Returns:
a transaction ticket.
Throws:
TxException - thrown if the transaction manager encounters an unexpected error situation.

setRollbackOnly

public static void setRollbackOnly()
                            throws TxException
Marks the current JTA transaction for rollback. The rollback is performed when the commitLevel() method is called on the transaction level that has started the JTA transaction.

Throws:
TxDemarcationException - thrown if no transaction is associated with the current thread.
TxException - thrown if the transaction manager encounters an unexpected error situation.

leaveLevel

public static void leaveLevel(TransactionTicket ticket)
                       throws TxException,
                              TxDemarcationException,
                              TxRollbackException
Finishes and leaves the transaction level associated with the given transaction ticket.

If the commitLevel() method has already been called on the transaction level identified by this ticket, this method has no further effect than finishing the current transaction level. Otherwise, if the commitLevel() method has not yet been called on this transaction level, the following two cases must be distinguished:

Finally, if a JTA transaction has been suspended on this transaction level because a new one was started, then this suspended transaction will be resumed before this method is left.

Parameters:
ticket - a transaction ticket.
Throws:
TxRollbackException - thrown to indicate problems during rollback of the transaction.
TxDemarcationException - thrown if the belance of the transaction demarcation calls has been violated.
TxException - thrown if the transaction manager encounters an unexpected error situation.

isTxActive

public static boolean isTxActive()
                          throws TxException
Checks whether the transaction associated with the current thread is active.

Throws:
TxException - thrown if the transaction manager encounters an unexpected error situation.

isTxMarkedRollback

public static boolean isTxMarkedRollback()
                                  throws TxException
Checks whether the transaction associated with the current thread is marked for rollback.

Throws:
TxException - thrown if the transaction manager encounters an unexpected error situation.
Access Rights

This class can be accessed from:


SC DC
[sap.com] ENGFACADE [sap.com] tc/je/txmanager/api


Copyright 2010 SAP AG Complete Copyright Notice