Introducing Transaction Guard and Application Continuity
Oracle Database 12c introduces two fundamental capabilities for ensuring continuity of applications after database outages:
- A foolproof way for applications to know the outcome of transactions
- The ability to mask outages by reconnecting to the database and replaying the workload
These capabilities are provided by two new features: Transaction Guard and Application Continuity.
- Transaction Guard is an API that applications use in error handling. It is a new and reliable way to return the outcome of the last transaction after a recoverable error has occurred. By itself, Transaction Guard can dramatically improve the end-user experience by erasing the doubt over whether the last transaction was committed or not.
- Application Continuity is a feature that masks recoverable outages from end users and applications. Application Continuity attempts to replay the transactional and nontransactional work that constitutes a database request. When replay is successful, the outage appears to the end user as if the execution was slightly delayed. With Application Continuity, the end user experience is improved because users may never sense that an outage has occurred. Furthermore, Application Continuity can simplify application development by removing the burden of dealing with recoverable outages.
What Is Transaction Guard?
Transaction Guard is a reliable protocol and API that applications use to provide a reliable commit outcome. The API is typically embedded in error handling and should be called following recoverable errors. The outcome indicates whether the last transaction was committed and completed. After the commit outcome is returned to the application, the outcome persists. Therefore, if Transaction Guard returns committed or uncommitted, the status stays this way. This enables the application or user to proceed with confidence.
Transaction Guard is used by Application Continuity and is automatically enabled by it, but it can also be enabled independently. Transaction Guard prevents the transaction being replayed by Application Continuity from being applied more than once. If the application has implemented application-level replay, integration with Transaction Guard can be used to ensure transaction idempotence; that is, executing the transaction multiple times has the same result as executing it only once.
Benefits of Transaction Guard
Transaction Guard is a powerful feature. Some of the benefits are:
- For applications that integrate Transaction Guard, users can know what happened to their last submission and proceed with confidence and certainty. Without Transaction Guard, doubt following a failure can lead to resubmitting a database request, which can cause logical corruption.
- Because it is integrated into the database kernel, Transaction Guard provides better performance and reliability than home-built code for idempotence.
How Transaction Guard Works
In the standard commit case, the database commits a transaction and returns a success message to the client. In the illustration shown above, the client submits a commit statement and receives a message stating that communication failed. This type of failure can occur due to several reasons, including a database instance failure or network outage. In this scenario, without Transaction Guard, the client does not know the outcome of the transaction.
Oracle Database solves the problem by using a globally unique identifier called a logical transaction ID (LTXID). When the application is running, both the database and client hold the logical transaction ID. The database supplies the client with a logical transaction ID at authentication and at each round trip from the client driver that executes one or more commit operations.
When a recoverable outage occurs, the logical transaction ID uniquely identifies the last database transaction submitted on the session that failed. A new PL/SQL interface (DBMS_APP_CONT.GET_LTXID_OUTCOME) interface returns the reliable commit outcome.
Using Transaction Guard
You may use Transaction Guard on each database in your system, including restarting on and failing over between single instance database, Real Application Clusters, Data Guard and Active Data Guard.
Transaction Guard is supported with the following Oracle Database 12c configurations:
- Single Instance Oracle RDBMS
- Real Application Clusters
- Data Guard
- Active Data Guard
- Multitenant including unplug/plug and for 12.2 relocates across the PDB/CDB, but excludes “with clone” option
- Global Data Services for the above database configurations
Transaction Guard supports all the transaction types below.
- Local commit
- Auto-commit and Commit on Success
- Commit embedded in PL/SQL
- DDL, DCL, and Parallel DDL
- Remote, Distributed commit
- XA transactions using One Phase Optimizations
The primary exclusions in Oracle Database12c release 12.2 are:
- Two Phase XA transactions
- Active Data Guard with read/write database links to another database
To enable Transaction Guard, set the service attribute COMMIT_OUTCOME=TRUE. Optionally, change the RETENTION_TIMEOUT service attribute to specify the amount of time that the commit outcome is retained. The retention timeout value is specified in seconds; the default is 86400 (24 hours), and the maximum is 2592000 (30 days).
Transaction Guard supports the following client drivers:
- 12c JDBC type 4 driver
- 12c OCI and OCCI client drivers
- 12c Oracle Data Provider for .NET (ODP.NET), Unmanaged Driver
- 12c ODP.NET, Managed Driver in ODAC 12c Release 4 or higher
Creating Services for Transaction Guard
To enable Transaction Guard, but not Application Continuity, create the service using SRVCTL and set only-commit_outcome to TRUE.
$ srvctl add service -db racdb -service app3 –serverpool Srvpool1 -commit_outcome TRUE -retention 86400 -failoverretry 30 -failoverdelay 10 –notification TRUE -rlbgoal SERVICE_TIME -clbgoal SHORT
You can use SRVCTL to modify an existing service to enable Transaction Guard, similar to the following command, where racdb is the name of your Oracle RAC database, and app2 is the name of the service you are modifying:
$ srvctl modify service -db racdb -service app2 -commit_outcome TRUE -retention 86400 -notification TRUE
In the preceding example, the -retention parameter specifies how long, in seconds, to maintain the history. Additionally the –notification parameter is set to TRUE, enabling FAN events. To use Transaction Guard, a DBA must grant permission, as follows:
GRANT EXECUTE ON DBMS_APP_CONT;
What Is Application Continuity?
Without Application Continuity, network outages, instance failures, hardware failures, repairs, configuration changes, patches, and so on can result in the failure of a user session followed by an error message of some sort. Application Continuity masks many recoverable database outages from applications and users. It achieves the masking by restoring the database session, the full session (including session state, cursors, and variables), and the last in-flight transaction (if there is one).
If the database session becomes unavailable due to a recoverable error, Application Continuity attempts to rebuild the session and any open transactions to the correct states. If the last transaction was successful and does not need to be reexecuted, the successful status is returned to the application. Otherwise, Application Continuity will replay the last in-flight transaction.
To be successful, the replay must return to the client exactly the same data that the client received previously in the original request. This ensures that any decisions based on previously queried data are honored during the replay. If the replay is successful, the application continues safely without duplication.
If the replay is not successful, the database rejects the replay and the application receives the original error. This ensures that the replay does not proceed if circumstances change between the original request and the replay.
Benefits of Application Continuity
Here are some benefits of Application Continuity:
- User service is uninterrupted when the request replay is successful.
- Application Continuity can be used to migrate the database sessions to the remaining servers without the users perceiving an outage.
- Masking outages that can be masked improves developer productivity. Error handling code will be invoked less often and can potentially be simplified.
- Replay often requires few or no application changes.
- Application Continuity is simple to configure
How Does Application Continuity Work?
Following is a description of a typical workflow involving Application Continuity:
- The client sends a work request to the application.
- The application sends the calls that make up the request to the database using the JDBC replay driver.
- The JDBC replay driver receives a Fast Application Notification (FAN) notification or a recoverable error.
- The replay driver performs the following actions:
- It checks that the request has replay enabled and that the replay initiation timeout has not expired. If all is in order, the driver obtains a new database session. If a callback is registered, the callback is executed to initialize the session.
- It checks with the database to determine whether the last transaction completed.
- If replay is required, the JDBC replay driver resubmits calls, receiving directions for each call from the database. Each call must result in the same client-visible state.
- When the last call is replayed, the replay driver ends the replay and returns to normal runtime mode.
- If the replay succeeds, the application responds normally to the user.
RAC and Application Continuity
Application Continuity is a feature that rapidly and transparently replays a request against the database after a recoverable error that makes the database session unavailable. The request can contain transactional and nontransactional work. With Application Continuity, the end user experience is improved by masking many system, communication, hardware, and storage problems from the end user.
When Application Continuity is used in conjunction with Oracle RAC, failed sessions can be quickly restarted and replayed on another RAC database instance. Using Application Continuity in conjunction with Oracle RAC provides protection against a wider variety of possible failures compared with using Application Continuity against a single instance database. Also, using Application Continuity in conjunction with Oracle RAC enables quicker replay compared with using Application Continuity in conjunction with Data Guard because reconnecting to another already running database instance can be completed in a few seconds while a Data Guard failover operation may take a few minutes.
Using Application Continuity
Below is a list of key points relating to the use of Application Continuity.
- Application Continuity recovers the database request, including any in-flight transaction and the database session states. The requests may include most SQL and PL/SQL, RPCs, and local JDBC calls. Note that for remote and distributed transactions, all databases involved must be release 12.1 or later.
- Application Continuity offers the ability to keep the original values for some Oracle functions, such as SEQUENCE.NEXTVAL, that change their values each time that they are called. This improves the likelihood that the replay will succeed.
- Application Continuity uses Transaction Guard. Transaction Guard tags each database session with a logical transaction ID (LTXID), so that the database recognizes whether a request committed the transaction before the outage.
- Application Continuity works in conjunction with Oracle Real Application Clusters (Oracle RAC), RAC One, and Oracle Active Data Guard.
- On the database server, the validation performed by Application Continuity is accelerated using processor extensions built into current SPARC and Intel chips.
- Application Continuity provides client support for thin JDBC, Universal Connection Pool, and WebLogic Server, OCI drivers, ODP.NET, OCI Session Pool, and Tuxedo
Configuration Guidelines for the supported clients:
- Use Oracle Database 12c Release 1 (22.214.171.124), or later, for Java. Use Oracle Database 12c Release 2 (12.2), or later, for OCI-based applications..
- For .NET applications, use ODP.NET, Unmanaged Driver 12.2, or later, connecting to an Oracle Database 12c Release 2 (12.2) or later. By default, Application Continuity is enabled for ODP.NET applications in this configuration.
- For Java-based applications, use Universal Connection Pool 12.1 (or later) or WebLogic Server 12.1.2 (or later) configured with the JDBC Replay data source; or for third party applications, including third party JDBC pools, use JDBC replay driver. For IBM WebSphere, Apache Tomcat, RedHat Spring, and custom Java solutions, the most effective solution is to use UCP as the pooled data source.
Creating Services for Application Continuity
To create a service for Application Continuity for a policy-managed RAC database:
$ srvctl add service -db racdb -service app2 –serverpool Srvpool1 -failovertype TRANSACTION -commit_outcome TRUE -replay_init_time 1800 -failoverretry 30 -failoverdelay 10 -retention 86400 -notification TRUE -rlbgoal SERVICE_TIME -clbgoal SHORT
To use Application Continuity, set the following mandatory service attributes:
- -FAILOVERTYPE=TRANSACTION to enable Application Continuity
- -COMMIT_OUTCOME=TRUE to enable Transaction Guard
To modify an existing service for Application Continuity:
$ srvctl modify service -db racdb -service app1 -clbgoal SHORT -rlbgoal SERVICE_TIME -failoverretry 30 -failoverdelay 10 -failovertype TRANSACTION -commit_outcome TRUE -replay_init_time 1800 -retention 86400 -notification TRUE
Additionally, you can set values for these other service parameters for Application Continuity and load balancing:
- REPLAY_INIT_TIME: This setting specifies the number of seconds within which replay must start. If replay does not start within the specified time then it is abandoned. Oracle recommends that you choose a value based on how long you will allow replay to be initiated. The default value is 300 seconds.
- RETENTION: This setting specifies the number of seconds that the commit outcome is stored in the database. The default is 86400 (24 hours), and the maximum is 2592000 (30 days).After a COMMIT has executed, if the session state was changed in that transaction, then it is not possible to replay the transaction to reestablish that state if the session is lost. When configuring Application Continuity, the applications are categorized depending on whether the session state after the initial setup is dynamic or static, and then whether it is correct to continue past a COMMIT operation within a request.
- DYNAMIC: (default) A session has a dynamic state if the session state changes are not fully encapsulated by the initialization, and cannot be fully captured in a callback at failover. Once the first transaction in a request commits, failover is internally disabled until the next request begins. This is the default mode that almost all applications should use for requests.
- STATIC: (special—on request) A session has a static state if all session state changes, such as NLS settings and PL/SQL package state, can be repeated in an initialization callback. This setting is used only for database diagnostic applications that do not change session state. Do not specify STATIC if there are any non-transactional state changes in the request that cannot be reestablished by a callback. If you are unsure what state to specify, use DYNAMIC.
- FAILOVERRETRY: This setting specifies the number of connection retries for each replay attempt. If replay does not start within the specified number of retries then it is abandoned. Oracle recommends a value of 30.
- FAILOVERDELAY: This setting specifies the delay in seconds between connection retries. Oracle recommends a value of 10.
- NOTIFICATION: FAN is highly recommended—set this value to TRUE to enable FAN for OCI and ODP.Net clients.
- CLBGOAL: For connection load balancing, use SHORT when using run-time load balancing.
- RLBGOAL: For run-time load balancing, set to SERVICE_TIME.