5 Using Transaction Guard

Transaction Guard provides a generic infrastructure for applications to use for at-most-once execution during planned and unplanned outages and duplicate submissions. Applications use the logical transaction ID to determine the outcome of the last transaction open in a database session following an outage.

Without Transaction Guard, applications that attempt to replay operations following outages can cause logical corruption by committing duplicate transactions.

Transaction Guard provides these benefits:

  • Preserves the commit outcome

  • Ensures a known outcome for every transaction

  • Provides at-most-once transaction execution

Overview of Transaction Guard

The main purpose of Transaction guard is to provide at-most execution semantics in case of failures. The semantics assure that end-user transactions are executed on time and at-most-once.

For current applications, in case of communication failure to the server, determining the outcome of the last commit operation in a guaranteed and scalable manner becomes a challenge. In many cases, the end users are asked to follow certain steps to avoid resubmitting duplicate request. For example, some applications warn users not to click the Submit button twice because if it is not followed, then users may unintentionally purchase the same items twice and submit multiple payments for the same invoice.

Without Transaction Guard, if a transaction has been started and 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. The transaction cannot be validly resubmitted if the non-transactional state is incorrect or if it already committed. In the absence of guaranteed commit and completion information, re-submission can lead to transactions applied more than once and in a session with the incorrect state.

It's possible to use global XA transactions to limit the problem described above. However, there is overhead associated with the protocols required for XA processing. Further, some features like application continuity are not available with XA transactions.

WebLogic Server Transaction Management integrates with Transaction Guard internally to determine the state (commit outcome) of transactions during failures. The benefits of this integration is reducing heuristic exceptions in the case of global transactions with more than one resource, and reducing system exceptions in the case of one-phase transactions with only one resource. The implementation of this integration is internal to WebLogic Server and does not require changes to the application code.

If there is an exception during the completion of the transaction, WebLogic Server uses Transaction Guard to determine the transaction result. No changes are needed in the application code.

For more information about Transaction Guard, see Transactions in the Oracle Database guide.

Enabling Transaction Guard

Transaction Guard must be configured both in the data source and in the database service.

Enabling Transaction Guard for WebLogic Data Sources

Except TwoPhaseCommit, transaction guard supports all non-XA Oracle data source driver types and all WebLogic data source transaction types like EmulateTwoPhaseCommit, OnePhaseCommit, LoggingLastResource, and None.Enable transaction guard support on a data source by setting the connection property weblogic.jdbc.commitOutcomeEnabled to true.
For example, the following is a sample from a WLST script that creates a data source:
jdbcSR = create(dsname, 'JDBCSystemResource') 
jdbcResource = jdbcSR.getJDBCResource() 
driverParams = jdbcResource.getJDBCDriverParams() 
driverProperties = driverParams.getProperties() 
tgprop = driverProperties.createProperty('weblogic.jdbc.commitOutcomeEnabled')
tgprop.setValue('true')

While trying to get the status of the transaction using Transaction Guard, it is possible for the operation to time out and the transaction will fail. The timeout for connections on a datasource with transaction type EmulateTwoPhaseCommit, OnePhaseCommit, or LoggingLastResource uses the XA completion-timeout value. The timeout for connections on a datasource with transaction type None (e.g., outside a transaction) is 10 seconds.

To override the default value, use the weblogic.jdbc.commitOutcomeRetrySeconds connection property. For example, add the following to the WLST script above.

tgseconds = driverProperties.createProperty(
'weblogic.jdbc. commitOutcomeRetrySeconds’)
tgseconds.setValue('60')

Note:

This feature is supported in a global transaction that has both XA and non-XA resources or has multiple EmulateTwoPhaseCommit resources. Global transactions with more than one participating resource can still experience heuristic outcomes. The use of the Transaction Guard feature on the datasource(s) does not guard against the inherent potential for non-atomic/heuristic outcome for this type of global transaction.

Enabling Transaction Guard for Database Service

The database service that is specified in the URL for the data source must be configured with the-commit_outcome parameter set to TRUE and optionally set the retention timeout.

For example:

srvctl modify service -d mydb -s myservice -e TRANSACTION -commit_outcome TRUE -retention 604800 -rlbgoal SERVICE_TIME -clbgoal SHORT

See Database Configuration for Transaction Guard

Data Source Statistics for Transaction Guard

Learn about Data source statistics available on the weblogic.management.runtime.JDBCDataSourceRuntimeMBean for transaction guard.

The following related statistics are available on the weblogic.management.runtime.JDBCDataSourceRuntimeMBean.

public long getResolvedAsCommittedTotalCount();

The cumulative total number of commit outcomes successfully resolved as committed in this data source since the data source was deployed.

public long getResolvedAsNotCommittedTotalCount();

The cumulative total number of commit outcomes successfully resolved as committed in this data source since the data source was deployed.

public long getUnresolvedTotalCount();

The cumulative total number of commit outcomes unsuccessfully resolved in this data source since the data source was deployed.

public long getCommitOutcomeRetryTotalCount();

The cumulative total number of commit outcome query retries conducted before resolving the outcome or exceeding the retry seconds in this data source since the data source was deployed.

See JDBCDataSourceRuntimeMBean.