VisiBroker for .NET Developer’s Guide : Using the Transaction service

Using the Transaction service
This chapter describes how to use transactions with VisiBroker for .NET. For more details on each of the APIs see the VisiBroker for .NET API documentation.
Configuring VisiBroker for .NET for transactions
To run with transactions, you must do the following steps:
1
2
When executing your application set the janeva.transactions property to true.
Creating VisiBroker for .NET-managed transactions
With VisiBroker for .NET-managed transactions you are using the Current interface for all transaction management. You are beginning transactions using Current and you are using Current for the implicit transaction propagation. This means that you will always originate your transactions using Current.Begin().
Current is an object that is valid for the entire process and manages the association of each thread's transaction context. Each thread has its own independent, isolated association with a transaction context.
In VisiBroker for .NET-managed transactions, transaction participants share the same transaction context because the transaction service transparently forwards the transaction context to each participant. This means that the state of a transaction is maintained as the originator calls on other objects to perform actions, which may in turn call other objects.
Obtaining a Current object reference
To gain access to a VisiBroker for .NET-managed transaction, you must obtain an object reference to the Current object. The Current object reference is valid throughout the process. The following steps describe the general process for obtaining a reference to a Current object, and are include code examples.
1
Call the orb.ResolveInitialReferences() method. This method obtains a reference to the Current object.
2
Narrow the returned object to a CosTransactions.Current object.
For example:
CORBA.ORB orb = ...;
CosTransactions.Current current = CosTransactions.CurrentHelper.Narrow(
orb.ResolveInitialReferences("TransactionCurrent"));
When you narrow to CosTransactions.Current, you specify your use of the original set of methods provided by the CosTransactions module.
Looking at the CosTransactions module
The CosTransactions module is the Transaction Service IDL that conforms to the final OMG Transaction Service document. This is the module to use to restrict yourself strictly to CORBA-compliant methods. The IDL for this module is contained in the file CosTransactions.idl.
Transaction service classes and interfaces
Current interface
The Current interface defines methods to:
Current methods
The following sections describe the important Current methods. For more details, see the VisiBroker for .NET API documentation.
Begin
This method creates a new transaction. Because nested transactions are not supported, this is always a top-level transaction.
The transaction context of the client thread is modified so that the thread is associated with the new transaction. If the client thread is already associated with a transaction, the CosTransactions.SubtransactionsUnavailable exception is raised.
Commit
This method commits the transaction associated with the client thread. The effect of this method is equivalent to calling the Commit method on the corresponding Terminator object.
If this transaction has been marked for rollback, or any Resource votes for Rollback, this call raises CORBA.TRANSACTION_ROLLEDBACK. If there is no current transaction, a CosTransactions.NoTransaction exception is raised. If the caller is not the transaction originator, Commit raises the exception CORBA.NO_PERMISSION.
Checks are made to ensure checked behavior.
On return from this method, the client thread is no longer associated with a transaction. Any attempt to use Current, as if there were a transaction, will raise an exception, such as NoTransaction or CORBA.TRANSACTION_REQUIRED, or will return a null object reference.
This method does not return until the transaction is complete, and all related Synchronization objects have been notified.
GetControl
This method returns a Control object reference that represents the transaction context currently associated with the client thread.
If the client thread is not associated with a transaction, a null object reference is returned.
GetStatus
This method returns an enumerated value (enum Status) that represents the status of the transaction associated with the client thread.
Calling this method is equivalent to calling the GetStatus method on the corresponding Coordinator object. If there is no transaction associated with the current thread, then the method returns CosTransactions.StatusNoTransaction.
The possible return values are:
GetTransactionName
This method returns a printable string that is a descriptive name for the transaction. This method is intended to assist in diagnostics and debugging.
The effect of this method is equivalent to calling the GetTransactionName method on the corresponding Coordinator object. If there is no transaction associated with the client thread, an empty string is returned.
Resume
Associates the client thread with the specified transaction. Typically, this is used to either
The client thread becomes associated with the specified transaction. If the client thread was already associated with a transaction, the previous transaction context is forgotten. If Resume is invoked with a NULL control, no transaction is associated with the current thread, and the transaction context is forgotten.
Caution
Any transaction context you set via Resume is propagated back to the invoking object.
Rollback
Rolls back the transaction associated with the client thread. This is equivalent to calling the Rollback method on the corresponding Terminator object. This method does not return until the transaction is complete, and all related Synchronization objects have been notified. On return from this method, the client thread is no longer associated with a transaction. Any attempt to use Current, as if there were a transaction, will raise an exception, such as CosTransactions.NoTransaction or CORBA.TRANSACTION_REQUIRED, or return a null object reference. If a heuristic occurs, this method will not throw a heuristic-related exception.
If the caller is not the transaction originator, Rollback raises the exception CORBA.NO_PERMISSION.
RollbackOnly
The method modifies the transaction associated with the client thread so that Rollback is the only possible transaction outcome. The effect of this request is equivalent to calling the RollbackOnly method on the corresponding Coordinator object. A client that is restricted from performing the Rollback operation, can nonetheless call RollbackOnly.
SetTimeout
This method establishes a new time-out for transactions started by subsequent calls to the Current.Begin method in all threads within this program.
To establish a new time-out, use these values of the seconds parameter:
Sets the new time-out to the specified number of seconds. If the seconds parameter exceeds the maximum time-out valid for a transaction service instance being used, then the new time-out is set to that maximum, to bring it in range.
Note
When a transaction, created by a subsequent call to Begin in any thread in the process, takes longer to start transaction completion than the established time-out, it will be rolled back. If the time-out occurs before the transaction enters the completion stage (begins two-phase or one-phase processing) the transaction will be rolled back. Otherwise, the time-out is ignored.
Suspend
This method suspends the transaction currently associated with the client thread and returns a Control object for that transaction. If the client thread is not associated with a transaction, a null object reference is returned.
The Control object can be passed to the Resume method to reestablish this context in the same thread or a different thread.
After the call to Suspend, no transaction is associated with the client thread. Any attempt to use Current, as if there were a transaction, will raise an exception, such as CosTransactions.NoTransaction or CORBA.TRANSACTION_REQUIRED, or return a null object reference.
TransactionFactory interface
The TransactionFactory interface defines methods that enable a program to initiate non-VisiBroker for .NET-managed transactions. The TransactionFactory interface gives programs direct control over the propagation of transaction context.
You acquire a TransactionFactory object the way you do any CORBA object; for example, by binding.
TransactionFactory methods
The following sections describe the important TransactionFactory methods. For more details, see the VisiBroker for .NET API documentation.
Create
This method accepts a time-out parameter (time_out) and creates a new transaction. It returns a Control object. The Control object can be used to manage or to control participation in the new transaction. The Control object can be used by any thread and passed around explicitly, just like any other CORBA object.
Note
Checked behavior cannot be provided for transactions that use this method.
To establish a new time-out, use the following values of the time_out parameter.
Sets the new time-out to the specified number of seconds. If the seconds parameter exceeds the maximum time-out valid for a transaction service instance being used, then the new time-out is set to that maximum, to bring it in range.
The new time-out applies only to the transaction created on this call. If a transaction does not start transaction completion (begin two-phase or one-phase processing) before the time-out expires, it will be rolled back.
Recreate
This method creates a new Control object using its PropagationContext parameter. The Control object can be used to manage or to control participation in the transaction. Applications will not normally call this method.
To get a transaction's PropagationContext, invoke the CosTransactions.CoordinatorOperations.GetTxcontext method on the transaction's Coordinator object.
Control interface
The Control interface enables a program to explicitly manage or propagate a transaction context. A Control object is implicitly associated with one specific transaction.
The Control interface defines two methods: GetCoordinator and GetTerminator. The GetCoordinator method returns a Coordinator object, which supports methods used by participants in the transaction. The GetTerminator method returns a Terminator object, which supports methods to complete the transaction. The Terminator and Coordinator objects support methods that are typically performed by different parties. Providing two objects enables each set of methods to be made available only to the parties that require those methods.
You can obtain a Control object by using one of the methods of the TransactionFactory (see “TransactionFactory interface”). You can also obtain a Control object for the current transaction (associated with a thread) through methods of the Current object. See descriptions of the GetControl or Suspend methods in “Current interface”.
Control methods
The following sections describe the important Control methods. For more details, see the VisiBroker for .NET API documentation.
GetCoordinator
This method returns a Coordinator object. The Coordinator provides methods that are called by participants in a transaction. These participants are typically either recoverable objects or agents of recoverable objects.
GetTerminator
This method returns a Terminator object. The Terminator can be used to rollback or commit the transaction associated with the Control. The CosTransactions.Unavailable exception is raised if the Control cannot provide the requested object due to the inability of the Terminator object to be transmitted to or be used in other execution environments.
Terminator interface
The Terminator interface supports methods to commit or roll back a transaction. Typically, these methods are used by the transaction originator, but any program that has access to a Terminator object for that transaction can commit or roll back the transaction.
Terminator methods
The following sections describe the important Terminator methods. For more details, see the VisiBroker for .NET API documentation.
Commit
Before committing the transaction, this method performs some checks. If the transaction has not been marked rollback only, and all of the participants in the transaction agree to commit, the transaction is committed and the operation terminates normally. Otherwise, the transaction is rolled back and the CORBA.TRANSACTION_ROLLEDBACK standard exception is raised.
If the report_heuristics parameter is true, the Transaction Service will report inconsistent or possibly inconsistent outcomes using the CosTransactions.HeuristicMixed and CosTransactions.HeuristicHazard exceptions when appropriate. Information about the Resources involved in a heuristic outcome will be written to a heuristic log file corresponding to the instance of the Transaction Service.
When a transaction is committed, all changes to recoverable objects made in the scope of this transaction are made permanent and visible to other transactions or clients.
Rollback
This method rolls back the transaction. When a transaction is rolled back, all changes to recoverable objects made in the scope of this transaction are rolled back. All Resources locked by the transaction are made available to other transactions as appropriate to the degree of isolation enforced by the Resources.
This method does not return until the transaction is complete and all related Synchronization objects have been notified.
Coordinator interface
The Coordinator interface provides methods that are used by participants in a transaction. These participants are typically either recoverable objects or agents of recoverable objects. Each Coordinator is implicitly associated with a single transaction.
Several of the Coordinator methods are equivalent, that is, they return the same result.
Similarly, certain methods return TRUE only when the target object and the parameter refer to the same Coordinator object. Therefore, the following methods are also equivalent:
And, the following methods are equivalent:
Coordinator methods
The following sections describe the important Coordinator methods. For more details, see the VisiBroker for .NET API documentation.
GetStatus
This method returns the status of the transaction associated with the target object, as an enumerated value (enum Status). If there is no transaction associated with the target object, then the method returns the value StatusNoTransaction.
Because VisiBroker for .NET does not support nested transactions, the GetStatus, GetTopLevelStatus and GetParentStatus methods return the same result.
The following are the possible return values, as defined in CosTransactions.idl:
For information about each Status value, see “GetStatus”.
GetTransactionName
This method returns a printable string that is a descriptive name for the transaction. This method is intended to assist with diagnostics and debugging. If there is no transaction associated with the client thread, an empty string is returned.
GetTxcontext
The GetTxcontext method returns a PropagationContext, which can be used by one Transaction Service domain to export a transaction to a new Transaction Service domain.
HashTransaction
This method returns a hash code for the transaction associated with the target object. Each transaction has a single hash code. The hash code can be used to efficiently compare Coordinators for inequality against the hash codes of other transactions. If the hash codes of two Coordinators are not equal, then they represent different transactions. If two hash codes are equal, then IsSameTransaction must be used to guarantee equality or inequality, because two Coordinators might have the same hash code but, in fact, represent two different transactions.
IsSameTransaction
This method returns true if, and only if, the target object and the parameter object both refer to the same transaction.
RegisterResource
This method registers the specified Resource as a participant in the transaction associated with the target object. When the transaction is terminated, the Resource will receive requests to prepare, commit, or rollback the updates performed as part of the transaction. For information on Resource methods, see “Resource interface”.
This method returns a RecoveryCoordinator that can be used by this Resource during recovery.
RegisterSynchronization
This method registers the specified Synchronization object so that it will be notified to perform the necessary processing before and after completion of the transaction. Such methods are described in the description of the Synchronization interface; see “Synchronization interface”.
RegisterSubtranAware
Because VisiBroker for .NET does not support nested transactions, this method always raises CosTransactions.SubtransactionsUnavailable.
RollbackOnly
This method modifies the transaction associated with the Coordinator so that rollback is the only possible transaction outcome.
RecoveryCoordinator interface
When a Resource is registered with the Coordinator, a RecoveryCoordinator is returned. The RecoveryCoordinator is implicitly associated with a single Resource registration request and can only be used by that Resource. In case recovery is necessary, the Resource can use the RecoveryCoordinator during the recovery process.
Also, the Resource can use the RecoveryCoordinator if it needs to know the current status of the transaction. For example, the Resource can set its own time-out, and if commit or rollback does not occur within the time-out, the Resource can invoke ReplayCompletion to determine the status of the transaction.
RecoveryCoordinator methods
The following section describes the RecoveryCoordinator methods. For more details, see the VisiBroker for .NET API documentation.
ReplayCompletion
This method notifies the Transaction Service that the Resource is available. This method is typically used during recovery, and can be used by the Resource to determine the status of the transaction.
Note
This method does not initiate completion.
Resource interface
VisiBroker for .NET uses a two-phase commit protocol to complete a top-level transaction with each Resource registered with it, that is, with each Resource that might change during the transaction. The Resource interface defines the methods invoked by the Transaction Service on each Resource. Each object supporting the Resource interface is implicitly associated with a single top-level transaction.
VisiBroker for .NET provides the Resource interface in the CosTransactions.idl file, but you must provide the implementation in your Resource. A typical application does not implement a Resource.
Resource methods
The following sections describe the important Resource methods. For more details, see the VisiBroker for .NET API documentation.
Commit
This method attempts to commit all changes associated with the Resource. If a heuristic outcome exception is raised, the Resource must keep the heuristic decision in persistent storage until the Forget method is performed so that it can return the same outcome in case Commit is invoked again during recovery. Otherwise, the Resource can immediately forget all knowledge of the transaction.
CommitOnePhase
This method requests the Resource to commit all changes made as part of the transaction. This method is an optimization for use when a transaction has only one participating Resource. This method can be called on the Resource, instead of first calling Prepare and then Commit or Rollback.
If a heuristic outcome exception is raised, the Resource must keep the heuristic decision in persistent storage until the Forget method is performed. This enables the Resource to return the same outcome in case CommitOnePhase is performed again during recovery. Otherwise, the Resource immediately forgets all knowledge of the transaction.
If a failure occurs during CommitOnePhase, it is called again when the failure is repaired. Since there is only a single Resource, the HeuristicHazard exception is used to report heuristic decisions related to that Resource.
Forget
When VisiBroker for .NET receives a heuristic exception, it records the exception. The Transaction Service will ultimately call Forget on the Resource. This means that the Resource can discard all information about the transaction that raised the heuristic exception. This method is called only if a heuristic exception was raised from Rollback, Commit, or CommitOnePhase.
Prepare
This method performs the prepare operation, the first step in the two-phase commit protocol for a Resource object. When finished, the method returns one of these Vote values.
All data changed as part of the transaction
A reference to the RecoveryCoordinator object
An indication that the Resource has been prepared
After returning VoteReadOnly or VoteRollback, the Resource can forget all knowledge of the transaction.
If a heuristic outcome exception is raised, the Resource must save the heuristic decision in persistent storage until the Forget method is called so that it can return the same outcome in case Prepare is called again.
Rollback
This method rolls back all updates associated with the Resource object.
If a heuristic outcome exception is raised, the Resource must save the heuristic decision in persistent storage until the Forget method is invoked. This enables the Resource to return the same outcome in case Rollback is called again during recovery. Otherwise, the Resource immediately forgets all knowledge of the transaction.
Synchronization interface
The Synchronization interface defines methods that enable a transactional object to be notified before the start of the two and one-phase commit protocol, and after its completion. In the CosTransactions module, the Synchronization interface provides two methods:
BeforeCompletion—Ensures that BeforeCompletion is invoked before starting to commit a transaction.
AfterCompletion—Ensures a transactional object is notified after the transaction has been completed. This applies to all transactions whether they were committed or rolled back.
Here are two limitations you should be aware of:
If the Transaction Service cannot contact your Synchronization object while trying to call BeforeCompletion, then the transaction will be rolled back. If a Synchronization object is unavailable after completion, it will be ignored.
Notes
In certain cases, AfterCompletion is called when BeforeCompletion was not called. BeforeCompletion is called only if a transaction is still continuing towards a commit at the outset of completion. AfterCompletion is always called (unless the Transaction Service crashes before the transaction completes).
Synchronization methods
The following sections describe the important Synchronization methods. For more details, see the VisiBroker for .NET API documentation.
AfterCompletion
This is a method that you write that performs customized processing after the completion of the transaction. It is essentially a callback.
Note
The AfterCompletion method is always invoked during normal processing.
IDL for the Synchronization interface inherits from the TransactionalObject interface. As a programmer, you are responsible for writing the implementation of an AfterCompletion method that conforms to the IDL.
If AfterCompletion is to be called in processing a particular transaction, the following actions must be taken:
1
2
The Synchronization object must be registered by getting the transaction's Coordinator, and calling the RegisterSynchronization method in Coordinator and Current. See the description for the RegisterSynchronization method in “Coordinator interface”. Registration must be done after the transaction is created and before the start of the two-phase commit.
Multiple Synchronization objects can be created and registered for a single transaction.
The Transaction Service calls this method after the two-phase commit protocol completes. As an example of its use, AfterCompletion can be used by a transactional object to discover the outcome of the transaction. This is particularly useful for transactional objects that are not also recoverable objects, and so are not automatically notified of the outcome.
You can call GetStatus to see whether or not the transaction has been marked for rollback.
Notice that because Synchronization inherits from TransactionalObject, the transaction context will be available through the Current object.
All exceptions will be ignored.
BeforeCompletion
This is a method that you write to perform customized processing at the onset of the completion of a transaction. It is called only if the transaction is still continuing towards successful completion. It is essentially a callback.
Note: The BeforeCompletion method is invoked after the application invokes commit, but before the Transaction Service begins transaction completion. The BeforeCompletion method is not invoked for a rollback request.
The IDL for the Synchronization interface inherits from the TransactionalObject interface. As a programmer, you are responsible for writing the implementation of a BeforeCompletion method that conforms to the IDL.
If BeforeCompletion is to be called when processing a particular transaction, the Synchronization object must be registered using the RegisterSynchronization method in the Coordinator interface. Register the Synchronization object from your transactional object or recoverable server. See the description for the RegisterSynchronization method in “Coordinator interface”. Registration must be done after the transaction is created and before the start of the two-phase commit.
Multiple Synchronization objects can be created and registered for a single transaction.
The Transaction Service calls this method after the transaction work has been done but before the two-phase commit protocol starts; that is, before Prepare is called on the participating Resource. The transaction service calls BeforeCompletion only if a transaction is still continuing towards a commit at the outset of completion. This means that Terminator.Commit was called and the transaction has not been marked for rollback. If Terminator.Rollback was called, or the first of several Synchronization objects marked the transaction for rollback, or the transaction was already marked for rollback, BeforeCompletion calls will not be called again for this transaction.
Within this method, you can ensure the transaction will be rolled back by calling the RollbackOnly method. You can also call GetStatus to see whether or not the transaction has been marked for rollback. At the time the method is called, however, you cannot rely upon the status to indicate whether or not the transaction will actually be committed.
Notice that because the Synchronization interface inherits from TransactionalObject, the transaction context will be available through the Current object. This means that BeforeCompletion can use all objects on the Current object, such as GetStatus and GetControl.
All CORBA exceptions raised by your Synchronization objects will result in the transaction being rolled back.
TransactionalObject interface
The TransactionalObject interface provides for the automatic propagation of transaction context on method calls of transactional objects. The TransactionalObject interface defines no methods.
Methods that work on transactions must have access to the transaction context. The transaction context can be made available to such methods in two ways:
Implicit propagation is the typical, and easiest, way. This is the capability that the TransactionalObject interface provides to your transactional objects. An instance of TransactionalObject can participate in implicit propagation. Implicit propagation is where the transaction context associated with the client thread is automatically propagated to TransactionalObject instances through method calls.
To use VisiBroker for .NET-managed transactions, all of your transactional objects must inherit from TransactionalObject. By using VisiBroker for .NET-managed transactions, you benefit from checked behavior.
The transaction context is always passed implicitly to an object that inherits from CosTransactions.TransactionalObject. In addition, a program may be passed a transaction context explicitly, as a parameter.