VisiTransact Guide : Coordinating transaction completion with Resource objects

Coordinating transaction completion with Resource objects
This section provides information about how you can participate in one- and two-phase commits using Resource object(s).
Understanding transaction completion
The transaction process described in “Model for a basic transaction” was a simple example that did not involve data. The following diagram expands on that earlier example to show the objects that are necessary when transactions involve data—Recoverable Server, Recoverable Object, Recovery Coordinator, and Resource object. In practice, several of these objects are encapsulated by transactional software for data, as shown in the figure below. These objects are shown so that you will understand the process going on underneath, and will recognize these interfaces in the IDL.
If you are using VisiTransact-managed transactions, this diagram also shows you the back-end objects (Coordinator, Terminator, and Recovery Coordinator) that the VisiTransact Transaction Service uses to perform the work of two-phase commits. You only manage these object directly if you are not using VisiTransact-managed transactions.
Figure 11
The table below describes the objects involved in two-phase commit.
Participating in transaction completion
“Completing a transaction” is where two-phase commit diverges from the simple example addressed in “Model for a basic transaction”. When the VisiTransact Transaction Service executes the two-phase commit process, it ensures that the entire transaction is either rolled back or committed atomically. In the first phase of the two-phase commit process, the Terminator asks the participants of the transaction if they can prepare the transaction to commit. If all participants vote that they can, the Terminator then tells all participants to commit the transaction during the second phase. If at least one participant votes that it is not prepared to commit, the Terminator instructs the participants to rollback the transaction.
Note
If a transactional application only involves one Resource, the VisiTransact Transaction Service initiates a one-phase commit process rather than a two-phase commit process.
The following sections expand on the concept of completing a transaction to explain the process of two-phase commit.
Resource object is registered for the transaction
Resource objects must be registered for all recoverable data involved in the transaction. The transactional object registers the Resource with the transaction's Coordinator for the recoverable data.
Figure 12
Transaction originator initiates transaction completion
The transaction originator notifies the Terminator that it wishes to complete the transaction, which initiates the two-phase commit process with the VisiTransact Transaction Service. This step replaces step 4 in “Completing a transaction”.
Figure 13
In this step, the same action is taking place, but you see behind the scenes that the invocation of commit() is actually handled by the Terminator.
Terminator tells Resource objects to prepare
Once the Terminator receives notice that the transaction originator wishes to commit the transaction, the Terminator contacts all Resource objects participating in the transaction, and notifies them they must prepare to commit the transaction. To do so, the Terminator invokes the prepare() method on all Resource objects registered with the transaction.
Figure 14
If only one Resource is registered with the Coordinator, the Terminator performs a one-phase commit as an optimization. To do so, it invokes commit_one_phase() on the Resource rather than invoking prepare() and then commit().
Any exception that occurs during the prepare phase causes a rollback of the transaction.
Resource objects return a vote to the terminator
When Resource objects are told to prepare, they respond to the Terminator with a vote:
If the Resource returns VoteRollback or VoteReadOnly, it will not be contacted again by the VisiTransact Transaction Service, and can safely destroy itself. For this example, let's assume that both Resource A and Resource B return VoteCommit.
Figure 15
Terminator decides whether to commit or roll back
Based on the votes received by the Resource objects, the Terminator determines whether the transaction will be committed or rolled back. At this point, the completion decision is made and logged. If any of the Resource objects return VoteRollback, raise exceptions, or invoke rollback_only(), the transaction will be rolled back by the Terminator.
If the transaction decision was to rollback, the Terminator invokes rollback() on all Resources—except those that returned VoteRollback or VoteReadOnly. If the decision is to commit, the Terminator invokes commit() on all Resources, and the two-phase commit process is finished.
For this example, both Resource objects involved with the transaction returned VoteCommit, so the Terminator object requests that the Resource objects commit the transaction.
Figure 16
Resource objects vote to commit the transaction
When a Resource object commits a transaction, it makes any data changed by the transaction visible to all readers of the data—the data stored by the recoverable object is changed according to the outcome of the transaction. Also, the Resource object stores other information in case of failure. Lastly, once the transaction has been committed, all objects associated with the transaction (the Coordinator, Terminator, and Recovery Coordinator) are removed.
Figure 17
Summary of steps for two-phase commit
As shown by the previous sections, the steps for two-phase commit are:
1
2
3
4
5
6
Summary of steps for single-phase commit
The steps for a single-phase commit are:
1
2
3
4
5
6
Summary of steps for a rollback
The steps for a rollback are:
1
2
3
Participating in transaction recovery after failure
If the VisiTransact Transaction Service (or its host) experiences a failure once the decision to commit the transaction has been logged, the Terminator proceeds to invoke commit() on all Resources once the VisiTransact Transaction Service and participating Resource objects are running again.
If the decision was to rollback, and the VisiTransact Transaction Service (or its host) experiences a failure, the VisiTransact Transaction Service considers the transaction to be rolled back once it is running again. This is because the VisiTransact Transaction Service does not keep track of Resources when a transaction is marked for rollback, and therefore it cannot proactively tell Resources to rollback. Instead, Resources must use the Recovery Coordinator (specifically, the replay_completion() method) to find out that the transaction rolled back.
If a VisiTransact Transaction Service fails before a Resource object has committed but after it has been prepared and the VisiTransact Transaction Service has not yet logged the decision, then the Resource is responsible for contacting the Recovery Coordinator and initiating transaction completion.
If a failure occurs and the Terminator cannot reach a registered Resource, the Terminator must keep trying to contact the Resource until it can be reached. In this way, atomic transactions are guaranteed because Resource objects will be restarted, and the VisiTransact Transaction Service will ensure that recoverable objects complete the transaction in conformance with the outcome.
These basic rules apply to transaction recovery following a failure of the VisiTransact Transaction Service:
If the decision to commit the transaction has been logged, the Terminator invokes commit() on all Resources, and the two-phase commit process is finished.