JBoss.orgCommunity Documentation

Chapter 4. Constructing an OTS application

4.1. Important notes for JBossTS
4.1.1. Initialization
4.1.2. Implicit context propagation and interposition
4.2. Writing applications using the raw OTS interfaces
4.3. Transaction context management
4.3.1. A transaction originator: indirect and implicit
4.3.2. Transaction originator: direct and explicit
4.4. Implementing a transactional client
4.5. Implementing a recoverable server
4.5.1. Transactional object
4.5.2. Resource object
4.5.3. Reliable servers
4.5.4. Examples
4.6. Failure models
4.6.1. Transaction originator
4.6.2. Transactional server
4.7. Summary

The OTS does not provide any Resource implementations. You need to provide these implementations. The interfaces defined within the OTS specification are too low-level for most situations. JBossTS is designed to make use of raw Common Object Services (COS) interfaces, but provides a higher-level API for building transactional applications and framework. This API automates much of the work involved with participating in an OTS transaction.

If you use implicit transaction propagation, ensure that appropriate objects support the TransactionalObject interface. Otherwise, you need to pass the transaction contexts as parameters to the relevant operations.

The commit operation of Current or the Terminator interface takes the boolean report_heuristics parameter. If the report_heuristics argument is false, the commit operation can complete as soon as the Coordinator makes the decision to commit or roll back the transaction. The application does not need to wait for the Coordinator to complete the commit protocol by informing all the participants of the outcome of the transaction. This can significantly reduce the elapsed time for the commit operation, especially where participant Resource objects are located on remote network nodes. However, no heuristic conditions can be reported to the application in this case.

Using the report_heuristics option guarantees that the commit operation does not complete until the Coordinator completes the commit protocol with all Resource objects involved in the transaction. This guarantees that the application is informed of any non-atomic outcomes of the transaction, through one of the exceptions HeuristicMixed or HeuristicHazard. However, it increases the application-perceived elapsed time for the commit operation.

A Recoverable Server includes at least one transactional object and one resource object, each of which have distinct responsibilities.

Example 4.3. Reliable server

/* 

  BankAccount1 is an object with internal resources. It inherits from both the TransactionalObject and the Resource interfaces:
*/
interface BankAccount1:
                    CosTransactions::TransactionalObject, CosTransactions::Resource
{
    ...
    void makeDeposit (in float amt);
    ...
};
/* The corresponding Java class is: */
public class BankAccount1
{
public void makeDeposit(float amt);
    ...
};
/*
  Upon entering, the context of the transaction is implicitly associated with the objects thread. The pseudo object
  supporting the Current interface is used to retrieve the Coordinator object associated with the transaction.
*/
void makeDeposit (float amt)
{
    org.omg.CosTransactions.Control c;
    org.omg.CosTransactions.Coordinator co;
    c = txn_crt.get_control();
    co = c.get_coordinator();
    ...
/*
  Before registering the resource the object should check whether it has already been registered for the same
  transaction. This is done using the hash_transaction and is_same_transaction operations.  that this object registers
  itself as a resource. This imposes the restriction that the object may only be involved in one transaction at a
  time. This is not the recommended way for recoverable objects to participate within transactions, and is only used as an
  example.  If more parallelism is required, separate resource objects should be registered for involvement in the same
  transaction.
*/
    RecoveryCoordinator r;
    r = co.register_resource(this);
    // performs some transactional activity locally
    balance = balance + f;
    num_transactions++;
    ...
    // end of transactional operation
};


The Transaction Service provides atomic outcomes for transactions in the presence of application, system or communication failures. From the viewpoint of each user object role, two types of failure are relevant:

The transaction originator and transactional server handle these failures in different ways.

Local failure

If a Transaction originator fails before the originator issues commit, the transaction is rolled back. If the originator fails after issuing commit and before the outcome is reported, the transaction can either commit or roll back, depending on timing. In this case, the transaction completes without regard to the failure of the originator.

External failure

Any external failure which affects the transaction before the originator issues commit causes the transaction to roll back. The standard exception TransactionRolledBack is raised in the originator when it issues commit.

If a failure occurs after commit and before the outcome is reported, the client may not be informed of the outcome of the transaction. This depends on the nature of the failure, and the use of the report_heuristics option of commit. For example, the transaction outcome is not reported to the client if communication between the client and the Coordinator fails.

A client can determine the outcome of the transaction by using method get_status on the Coordinator. However, this is not reliable because it may return the status NoTransaction, which is ambiguous. The transaction could have committed and been forgotten, or it could have rolled back and been forgotten.

An originator is only guaranteed to know the transaction outcome in one of two ways.

When you develop OTS applications which use the raw OTS interfaces, be aware of the following items:

The OTS does not provide any Resource implementations.