One of the fundamental problems for recovering applications after an outage is that the commit message that is sent back to the client is not durable. If there is a communication disruption between the client and the server, then the client receives an error message indicating that the communication failed (also called a recoverable error ). This error does not inform the application whether the submission executed any commit operations; or if a procedural call ran to completion executing all expected commits and session state changes or failed part way through; or worse yet, is still running disconnected from the client.
Transaction Guard provides a generic protocol and API for applications to use for at-most-once execution in case of planned and unplanned outages and repeated submissions. Applications use a new concept called the logical transaction ID (LTXID) to determine the outcome of the last transaction open in a database session following an outage. Without using Transaction Guard, applications that attempt to retry operations following outages can cause logical corruption by committing duplicate transactions. Application Continuity uses this feature, and it is available to other applications to determine the last outcome on a failed session.
Without Transaction Guard, if a transaction has been started and a commit has been issued, the commit message that is sent back to the client is not durable. The client is left not knowing whether the transaction committed or not. The transaction cannot be validly resubmitted if the non-transactional state is incorrect or if it is committed. In the absence of guaranteed commit and completion information, resubmission can cause transactions to be applied more than once. Continuing to process a committed but not completed transaction can result in the application using a database session that is in the wrong state.
In Oracle Database 12c, Transaction Guard provides a new, fully integrated tool for applications to use to achieve idempotence automatically and transparently, and in a manner that scales. Transaction Guard uses Logical Transaction ID (LTXID) to avoid submitting duplicate transactions. This is referred to as transaction idempotence. The LTXID persists on commit and is reused following a rollback. During normal runtime, a LTXID is automatically held in the session at both the client and server for each database transaction. At commit, the LTXID is persisted as part of committing the transaction and the next LTXID to use is returned to the client.
The following example describes how Application Continuity or a third-party application uses Transaction Guard:
Client receives a FAN down event or a recoverable error.
When you are using FAN, the FAN driver automatically aborts the dead session.
If it is a recoverable error, then Application Continuity uses Transaction Guard to determine the outcome of the dead session:
Get the last LTXID from the dead session using the APIs provided by the client drivers:
getLTXID for JDBC,
OCI_ATTR_GET with LTXID for Oracle Call Interface, and
LogicalTransactionId for ODP.NET.
Obtain a new session.
Call the PL/SQL procedure
GET_LTXID_OUTCOME with the last LTXID obtained from the failed session.
If the outcome of the transaction is COMMITTED and COMPLETED, then return the result of that transaction to the application.
If the outcome of the transaction is COMMITTED and NOT USER_CALL_COMPLETED, then return COMMITTED and a warning that the user call was not completed.
If the outcome of the transaction is not COMMITTED, then, if needed, cleanup any state left behind from the last request and resubmit the last request.
Oracle Database Development Guide for more information about Transaction Guard