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.
Figure 11
“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.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”.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.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.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().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.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 the decision to commit the transaction has been logged, the Terminator invokes commit() on all Resources, and the two-phase commit process is finished.
•