Programming WebLogic JTA
Logging Last Resource Transaction Optimization
WebLogic Server includes support for the Logging Last Resource (LLR) transaction optimization through JDBC data sources. LLR is a performance enhancement option that enables one non-XA resource to participate in a global transaction with the same ACID guarantee as XA. LLR is a refinement of the “Last Agent Optimization.” It differs from Last Agent Optimization in that it is transactionally safe. The LLR resource uses a local transaction for its transaction work. The WebLogic Server transaction manager prepares all other resources in the transaction and then determines the commit decision for the global transaction based on the outcome of the LLR resource's local transaction.
In a global two-phase commit (2PC) transaction with an LLR participant, the WebLogic Server transaction manager follows these basic steps:
- Calls prepare on all other (XA-compliant) transaction participants.
- Inserts a commit record to a table on the LLR participant (rather than to the file-based transaction log).
- Commits the LLR participant's local transaction (which includes both the transaction commit record insert and the application's SQL work).
- Calls commit on all other transaction participants.
- After the transaction completes successfully, lazily deletes the database transaction log entry as part of a future transaction.
The following sections provide more information about LLR transaction processing in WebLogic Server:
- About the LLR Optimization Transaction Optimization
- Logging Last Resource Processing Details
- LLR Database Table Details
- Failure and Recovery Processing for LLR
- Optimizing Performance with LLR
For more information about the advantages of LLR, see “Understanding the Logging Last Resource Transaction Option” in Configure WebLogic JDBC.
About the LLR Optimization Transaction Optimization
In many cases a global transaction becomes a two-phase commit (2PC) transaction because it involves a database operation (using JDBC) and another non-database operation, such as a message queueing operation (using JMS). In cases such as this where there is one database participant in a 2PC transaction, the Logging Last Resource (LLR) Optimization transaction option can significantly improve transaction performance by eliminating some of the XA overhead for database processing and by avoiding the use of JDBC XA drivers, which typically are less efficient than non-XA drivers. The LLR transaction option does not incur the same data risks as borne by the Emulate Two-Phase Commit JDBC data source option and the NonXAResource resource adapter (Connector) option.
Logging Last Resource Processing Details
At server boot or data source deployment, LLR data sources load or create a table on the database from which the data source pools database connections. The table is created in the schema determined by the user specified to create database connections. If the database table cannot be created or loaded, then server boot will fail.
Within a global transaction, the first connection obtained from an LLR data source reserves an internal JDBC connection that is dedicated to the transaction. The internal JDBC connection is reserved on the specific server that is also the transactions' coordinator. All subsequent transaction operations on any connections obtained from a same-named data source on any server are routed to this same single internal JDBC connection.
When an LLR transaction is committed, the WebLogic Server transaction manager handles the processing transparently. From an application perspective, the transaction semantics remain the same, but from an internal perspective, the transaction is handled differently than standard XA transactions. When the application commits the global transaction, the WebLogic Server transaction manager atomically commits the local transaction on the LLR connection before committing transaction work on any other transaction participants. For a two-phase commit transaction, the transaction manager also writes a 2PC record on the database as part of the same local transaction. After the local transaction completes successfully, the transaction manager calls commit on all other global transaction participants. After all other transaction participants complete the commit phase, the related LLR 2PC transaction record is freed for deletion. The transaction manager will lazily delete the transaction record after a short interval or with another local transaction.
If the application rolls back the global transaction or the transaction times out, the transaction manager rolls back the work in the local transaction and does not store a 2PC record in the database.
To enable the LLR transaction optimization, you create a JDBC data source with the Logging Last Resource transaction protocol, then use database connections from the data source in your applications. WebLogic Server automatically creates the required table on the database.
See “Create LLR-enabled JDBC data sources” in the Administration Console Online Help. Also see “Understanding the Logging Last Resource Transaction Option” in Configure WebLogic JDBC.
For a list of data source configuration and usage requirements and limitations, see:
- “Programming Considerations and Limitations for LLR Data Sources” in Configure WebLogic JDBC
- “Administrative Considerations and Limitations for LLR Data Sources” in Configure WebLogic JDBC
LLR Database Table Details
Each WebLogic server instance maintains a database "LLR" table on the database to which a JDBC LLR data source pools database connections. These tables are used for storing transaction log records, and are automatically created. If multiple LLR data sources are deployed on the same WebLogic server instance and connect to the same database instance and database schema, they will also share the same LLR table.
LLR table names are automatically generated unless administrators choose to configure them. The default table name is WL_LLR_SERVERNAME. For some DBMSs, the maximum length for a table name is 18 characters. You should consider maximum table name length when configuring your environment.
Note the following restrictions with regard to LLR database tables:
- The server will not boot if an LLR table is unreachable during boot. LLR transaction records must be available to correctly resolve in-doubt transactions during recovery, which runs automatically at server startup.
- Multiple servers must not share the same LLR table. On server startup, WebLogic Server checks to make sure that the domain and server name of the JDBC data source match the domain and server name stored in the table when the table is created. If WebLogic Server detects that more than one server is sharing the same LLR table, WebLogic Server will shut down one or more of the servers.
To change the table name used to store transaction log records for the resource, follow these steps:
- In the Change Center in the upper-left corner of the Administration Console window, click Lock & Edit to start a configuration editing session.
- On the Server: Configuration: General page, click to Advanced to show the advanced configuration options. See
- In JDBC LLR Table Name, enter the name of the table to use to store transaction records for the resource, then click Save. See Server: Configuration: General.
- Repeat steps 2 and 3 for each server on which the LLR-enabled data source is deployed.
- Click Activate Changes in the Change Center.
You must restart all servers for the change to take effect.
LLR Table Transaction Log Records
For each committed 2PC LLR transaction, the transaction manager automatically inserts a transaction record into an LLR database table. Once LLR transactions complete, the transaction manager lazily deletes their transaction records. If an LLR table transaction log record delete fails, the server will log a warning message and retry the delete again later.
If you need to move a database that contains LLR transaction records, make sure you move the LLR table contents to the new database so that transactions can be completed properly.
Caution: Do not manually delete the LLR transaction records or the LLR table in a production system. Doing so can lead to silent heuristic transaction failures which will be not logged.
Failure and Recovery Processing for LLR
In general, the WebLogic transaction manager processes transaction failures in the following way:
- For two-phase commit errors that occur before the local transaction commit is attempted, the transaction manager immediately throws a transaction rolled back exception.
- For two-phase commit errors that occur during the local transaction commit, the behavior depends on whether the transaction record is written to the database:
- If the record is written, the transaction manager commits the transaction.
- If the record is not written, the transaction manager rolls back the transaction.
- If it is unknown whether the record is written, the transaction manager throws an ambiguous commit failure exception and attempts to complete the transaction every 5 seconds until the transaction abandon timeout. If the transaction is still incomplete, the transaction manager logs an abandoned transaction message.
Coordinating Server Crash
If a transaction's coordinating server crashes before an LLR resource stores its transaction log record or before an LLR resource commits, the transaction rolls back. If the server crashes after the LLR resource is committed, the transaction will eventually fully commit. During server boot, the transaction coordinator will use the LLR resource to read the transaction log record from the database and then use the recovered information to commit any unfinished work on any participating non-LLR XA resources.
JDBC Connection Failure
If the JDBC connection in an LLR resource fails during a 2PC transaction record insert, the transaction manager rolls back the transaction.
If the JDBC connection in an LLR resource fails during the commit of the local transaction, the result depends on whether the transaction is a one-phase commit (1PC, where the LLR resource is the only participant) or 2PC:
- For a 1PC transaction, the transaction will be fully committed, fully rolled back, or block waiting for the resolution of the local transaction. The outcome of the transaction is fully ACID because it will eventually be fully committed or fully rolled back.
- For a 2PC transaction, the outcome is as described in Failure and Recovery Processing for LLR.
LLR Transaction Recover During Server Startup
During server startup, the transaction manager for each WebLogic server must recover incomplete transactions coordinated by the server, including LLR transactions. To do so, each server will attempt to read the transaction records from the LLR database tables for each LLR data source. If the server cannot access the LLR database tables or if the recovery fails, the server will not start and the transaction manager will mark the server with a bad health state: HealthState.HEALTH_FAILED.
If a timeout occurs during recovery, it may be due to unresolved local transactions that have locked rows within the LLR log tables. Such local transactions must be resolved so that the transaction manager can determine the state of the global transaction whose record is stored in the locked row. Local database transactions can only be diagnosed and resolved using each database's specific tools (the commands differ from database to database).
Failover Considerations for LLR
Consider the following notes and limitations with regard to failover with LLR:
- The file-based transaction log (TLog) is still required for LLR transactions:
- TLog still stores transaction manager “checkpoint” records
- TLog must still be reachable or copied on failover
- LLR supports server migration and transaction recovery service migration. To use the transaction recovery service migration, ensure that each LLR resource be targeted to either the cluster or the set of candidate servers in the cluster. See Recovering Transactions For a Failed Clustered Server.
Optimizing Performance with LLR
This section includes the following information:
- Optimizing Transaction Coordinator Location
- Varied Performance for Read-Only Operations through an LLR Data Source
Optimizing Transaction Coordinator Location
Within a global transaction with an LLR participant, WebLogic Server automatically routes all connection operations to the transaction's coordinating server. This routing can be expensive. You may see better performance if you optimize your applications to run directly on the coordinating server if possible, and optimize your applications to use connection instances that are directly hosted on the coordinator.
For client applications that begin a transaction, the coordinator of transaction is the first WebLogic server the client calls under the transaction (any RMI, EJB, JDBC, or JMS call). In the JMS case, this is the server that hosts the client's JMS connection, which is not necessarily the same as the server that hosts the JMS destination.
For server side applications, the coordinator of the transaction is the local server if a local resource is invoked first (including JMS destinations and JDBC connections) unless a remote server is called first (any remotely hosted JDBC connection, EJB, RMI call, or JMS connection). This includes remote servers in other clusters or domains.
Varied Performance for Read-Only Operations through an LLR Data Source
The LLR optimization provides a significant increase in performance for insert, update, and delete operations. However, for read operations with LLR, performance is somewhat slower than read operations with XA. For best performance, you may want to configure a non-LLR JDBC data source for read-only operations.