Administering Transactions
This chapter discusses how to manage the transaction service for the Payara Server environment by using the asadmin
command-line utility.
Instructions for manually recovering transactions are also included.
Instructions for accomplishing the tasks in this chapter by using the Administration Console are contained in the Administration Console online help.
For more information about the Java Transaction API (JTA) and Java Transaction Service (JTS), see the following sites:
You might also want to read Transactions.
About Transactions
A transaction is a series of discreet actions in an application that must all complete successfully. By enclosing one or more actions in an indivisible unit of work, a transaction ensures data integrity and consistency. If all actions do not complete, the changes are rolled back.
For example, to transfer funds from a checking account to a savings account, the following steps typically occur:
-
Check to see if the checking account has enough money to cover the transfer.
-
Debit the amount from the checking account.
-
Credit the amount to the savings account.
-
Record the transfer to the checking account log.
-
Record the transfer to the savings account log.
These steps together are considered a single transaction.
If all the steps complete successfully, the transaction is committed. If any step fails, all changes from the preceding steps are rolled back, and
the checking account and savings account are returned to the states they were in before the transaction started.
This type of event is called a rollback
. A normal transaction ends in either a committed state or a rolled back state.
The following elements contribute to reliable transaction processing by implementing various APIs and functionalities:
-
Transaction Manager. Provides the services and management functions required to support transaction demarcation, transactional resource management, synchronization, and transaction context propagation.
-
Payara Server. Provides the infrastructure required to support the application runtime environment that includes transaction state management.
-
Resource Manager. Through a resource adapter, the resource manager provides the application access to resources. The resource manager participates in distributed transactions by implementing a transaction resource interface used by the transaction manager to communicate transaction association, transaction completion, and recovery work. An example of such a resource manager is a relational database server.
-
Resource Adapter. A system-level software library is used by Payara Server or a client to connect to a resource manager. A resource adapter is typically specific to a resource manager. The resource adapter is available as a library and is used within the address space of the client using it. An example of such a resource adapter is a Java Database Connectivity (JDBC) driver. For information on supported JDBC drivers, see Configuration Specifics for JDBC Drivers.
-
Transactional User Application. In the Payara Server environment, the transactional user application uses Java Naming and Directory Interface (JNDI) to look up transactional data sources and, optionally, the user transaction). The application might use declarative transaction attribute settings for enterprise beans, or explicit programmatic transaction demarcation. For more information, see The Transaction Manager, the Transaction Synchronization Registry, and UserTransaction in the Payara Server Application Development section.
Transaction Resource Managers
There are three types of transaction resource managers:
-
Databases - Use of transactions prevents databases from being left in inconsistent states due to incomplete updates. For information about JDBC transaction isolation levels, see Using JDBC Transaction Isolation Levels in the Payara Server Application Development section.
The Payara Server supports a variety of JDBC XA drivers. For configurations of supported and other drivers, see Configuration Specifics for JDBC Drivers. -
Java Message Service (JMS) Providers - Use of transactions ensures that messages are reliably delivered. The Payara Server is integrated with Open Message Queue, a fully capable JMS provider. For more information about transactions and the JMS API, see Administering the Java Message Service (JMS).
-
J2EE Connector Architecture (CA) components - Use of transactions prevents legacy EIS systems from being left in inconsistent states due to incomplete updates. For more information about connectors, see Administering EIS Connectivity.
Transaction Scope
A local transaction involves only one non-XA resource and requires that all participating application components execute within one process. Local transaction optimization is specific to the resource manager and is transparent to the Jakarta EE application.
In the Payara Server, a JDBC resource is non-XA if it meets either of the following criteria:
-
In the JDBC connection pool configuration, the DataSource class does not implement the javax.sql.XADataSource interface.
-
The Resource Type setting is not set to javax.sql.XADataSource.
A transaction remains local if the following conditions remain true:
-
One and only one non-XA resource is used. If any additional non-XA resource is used, the transaction is aborted, because the transaction manager must use XA protocol to commit two or more resources.
-
No transaction importing or exporting occurs.
Transactions that involve multiple resources or multiple participant processes are distributed or global transactions.
A global transaction can involve one non-XA resource if last agent optimization is enabled. Otherwise, all resources must be XA.
The use-last-agent-optimization
property is set to true
by default. For details about how to set this property,
see Configuring the Transaction Service.
If only one XA resource is used in a transaction, one-phase commit occurs, otherwise the transaction is coordinated with a two-phase commit protocol.
A two-phase commit protocol between the transaction manager and all the resources enlisted for a transaction ensures that either all the resource managers
commit the transaction or they all abort. When the application requests the commitment of a transaction, the transaction manager issues a PREPARE_TO_COMMIT
request to
all the resource managers involved. Each of these resources can in turn send a reply indicating whether it is ready for commit (PREPARED
) or not (NO
).
Only when all the resource managers are ready for a commit does the transaction manager issue a commit request (COMMIT
) to all the resource managers. Otherwise, the
transaction manager issues a rollback request (ABORT
) and the transaction is rolled back.
Configuring the Transaction Service
You can configure the transaction service in the Payara Server in the following ways:
-
To configure the transaction service using the Administration Console, open the Transaction Service component under the relevant configuration. For details, click the Help button in the Administration Console.
-
To configure the transaction service, use the
set
subcommand to set the following attributes.
The following examples show theserver-config
configuration, but values for any configuration can be set. For example, if you create a cluster namedcluster1
and a configuration namedcluster1-config
is automatically created for it, you can usecluster1-config
in theset
subcommand to get the transaction service settings for that cluster.server-config.transaction-service.automatic-recovery = false server-config.transaction-service.heuristic-decision = rollback server-config.transaction-service.keypoint-interval = 2048 server-config.transaction-service.retry-timeout-in-seconds = 600 server-config.transaction-service.timeout-in-seconds = 0 server-config.transaction-service.tx-log-dir = domain-dir/logs
You can also set these properties:
server-config.transaction-service.property.oracle-xa-recovery-workaround = true server-config.transaction-service.property.sybase-xa-recovery-workaround = false server-config.transaction-service.property.disable-distributed-transaction-logging = false server-config.transaction-service.property.xaresource-txn-timeout = 0 server-config.transaction-service.property.pending-txn-cleanup-interval = -1 server-config.transaction-service.property.use-last-agent-optimization = true server-config.transaction-service.property.delegated-recovery = false server-config.transaction-service.property.wait-time-before-recovery-insec = 60 server-config.transaction-service.property.purge-cancelled-transactions-after = 0 server-config.transaction-service.property.commit-one-phase-during-recovery = false server-config.transaction-service.property.add-wait-point-during-recovery = 0 server-config.transaction-service.property.db-logging-resource = jdbc/TxnDS server-config.transaction-service.property.xa-servername = myserver
Default property values are shown where they exist. For db-logging-resource
and xa-servername
, typical values are shown. Values that are not self-explanatory are as follows:
-
The
xaresource-txn-timeout
default of0
means there is no timeout. The units are seconds. -
The
pending-txn-cleanup-interval
default of-1
means the periodic recovery thread doesn’t run. The units are seconds. -
The
purge-cancelled-transactions-after
default of0
means cancelled transactions are not purged. The units are the number of cancellations in between purging attempts. -
The
add-wait-point-during-recovery
property does not have a default value. If this property is unset, recovery does not wait. The units are seconds. -
The
db-logging-resource
property does not have a default value. It is unset by default. However, if you setdb-logging-resource
to an empty value, the value used isjdbc/TxnDS
. -
The
xa-servername
property does not have a default value. Use this property to override server names that can cause errors.
You can use theget
subcommand to list all the transaction service attributes and the properties that have been set.
Changingkeypoint-interval
,retry-timeout-in-seconds
, ortimeout-in-seconds
does not require a server restart. Changing other attributes or properties requires a server restart.-
You can also set the following system properties:
ALLOW_MULTIPLE_ENLISTS_DELISTS=false JTA_RESOURCE_TABLE_MAX_ENTRIES=8192 JTA_RESOURCE_TABLE_DEFAULT_LOAD_FACTOR=0.75f
The
JTA_RESOURCE_TABLE_DEFAULT_LOAD_FACTOR
default is the defaultMap
resizing value.
-
Managing the Transaction Service for Rollbacks
You can roll back a single transaction by using the asadmin
subcommands described in this section. To do so, the transaction service
must be stopped (and later restarted), allowing you to see the active
transactions and correctly identify the one that needs to be rolled
back.
To Stop the Transaction Service
Use the freeze-transaction-service
subcommand in remote mode to stop the transaction service. When the transaction service is stopped,
all in-flight transactions are immediately suspended. You must stop the transaction service before rolling back any in-flight transactions.
Running this subcommand on a stopped transaction subsystem has no effect. The transaction service remains suspended until you restart it by using
the unfreeze-transaction-service
subcommand.
-
Ensure that the server is running. Remote subcommands require a running server.
-
Stop the transaction service by using the
freeze-transaction-service
subcommand.
To Roll Back a Transaction
In some situations, you might want to roll back a particular transaction. Before you can roll back a transaction, you must first stop the transaction
service so that transaction operations are suspended.
Use the rollback-transaction
subcommand in remote mode to roll back a specific transaction.
-
Ensure that the server is running. Remote subcommands require a running server.
-
Enable monitoring using the
set
subcommand. For example:asadmin> set cluster1-config.monitoring-service.module-monitoring-levels.transaction-service=HIGH
-
Use the
freeze-transaction-service
subcommand to halt in-process transactions. See To Stop the Transaction Service. -
Identify the ID of the transaction you want to roll back.
To see a list of IDs of active transactions, use theget
subcommand with the--monitor
option to get the monitoring data for theactiveids
statistic. See Transaction Service Statistics. For example:asadmin> get --monitor instance1.server.transaction-service.activeids-current
-
Roll back the transaction by using the
rollback-transaction
subcommand.
The transaction is not rolled back at the time of this command’s execution, but only marked for rollback. The transaction is rolled back when it is completed.
To Restart the Transaction Service
Use the unfreeze-transaction-service
subcommand in remote mote to resume all the suspended in-flight transactions. Run this subcommand to restart the
transaction service after it has been frozen.
-
Ensure that the server is running. Remote subcommands require a running server.
-
Restart the suspended transaction service by using the
unfreeze-transaction-service
subcommand.
Determining Local Transaction Completion at Shutdown
When you shut down a Payara Server instance, all database connections are closed. When an Oracle JDBC driver-based database connection is closed in the middle of a non-XA transaction, all pending changes are committed. Other databases usually roll back pending changes when a connection is closed without being explicitly committed. To determine the exact behavior for your database, refer to the documentation from your JDBC driver vendor.
To explicitly specify whether Payara Server commits or rolls back
non-XA transactions at server shutdown, set the com.sun.enterprise.in-progress-local-transaction.completion-mode
JVM option to either commit
or rollback
using the create-jvm-options
subcommand. For example:
asadmin> create-jvm-options -Dcom.sun.enterprise.in-progress-local-transaction.completion-mode=rollback
Recovering Transactions
There are some situations where the commit or rollback operations might be interrupted, typically because the server crashed or a resource manager crashed. Crash situations can leave some transactions stranded between steps. Payara Server is designed to recover from these failures. If the failed transaction spans multiple servers, the server that started the transaction can contact the other servers to get the outcome of the transaction. If the other servers are unreachable, the transaction uses heuristic decision information to determine the outcome.
Automatic Transaction Recovery
Payara Server can perform automatic recovery in these ways:
-
Pending transactions are completed upon server startup if
automatic-recovery
is set totrue
. -
Periodic automatic recovery is performed by a background thread if the
pending-txn-cleanup-interval
property is set to a positive value.
Changing these settings requires a server restart. For more information about how to change these settings, see Configuring the Transaction Service. If commit fails during recovery, a message is written to the server log.
To Manually Recover Transactions
Use the recover-transactions
subcommand in remote mode to manually recover transactions that were pending when a resource or a server instance failed.
For a standalone server, do not use manual transaction recovery to recover transactions after a server failure. For a standalone server, manual transaction recovery can recover transactions only when a resource fails, but the server is still running. If a standalone server fails, only the full startup recovery process can recover transactions that were pending when the server failed.
For an installation of multiple server instances, you can use manual transaction recovery from a surviving server instance to recover transactions after a server failure. For manual transaction recovery to work properly, transaction logs must be stored on a shared file system that is accessible to all server instances. See Transaction Logging.
When you execute recover-transactions
in non-delegated mode, you can recover transactions that didn’t complete two-phase commit because of a resource crash.
To use manual transaction recovery in this way, the following conditions must be met:
-
The
recover-transactions
command should be executed after the resource is restarted. -
Connection validation should be enabled so the connection pool is refreshed when the resource is accessed after the recovery.
If commit fails during recovery, a message is written to the server log.
A JMS resource crash is handled the same way as any other resource. You can list in-doubt Open Message Queue transactions using the imqcmd list txn subcommand.
|
-
Ensure that the server is running. Remote subcommands require a running server.
-
Manually recover transactions by using the
recover-transactions
subcommand.
Distributed Transaction Recovery
To enable cluster-wide automatic recovery, you must first facilitate storing of transaction logs in a shared file system. See Transaction Logging.
Next, you must set the transaction service’s delegated-recovery
property to true
(the default is false
). For information about setting
tx-log-dir
and delegated-recovery
, see Configuring the Transaction Service.
Recovery Workarounds and Limitations
The Payara Server provides workarounds for some known issues with transaction recovery implementations.
These workarounds do not imply support for any particular JDBC driver. |
General Recovery Limitations
The following general limitations apply to transaction recovery:
-
Recovery succeeds if there are no exceptions during the process. This is independent of the number of transactions that need to be recovered.
-
Only transactions that did not complete the two-phase commit can be recovered (one of the XA resources failed or Payara Server crashed after resources were prepared).
-
Manual transaction recovery cannot recover transactions after a server crash on a standalone server instance. Manual operations are intended for cases when a resource dies unexpectedly while the server is running. In case of a server crash, only startup recovery can recover in-doubt transactions.
-
It is not possible to list transaction IDs for in-doubt transactions.
-
Delegated transaction recovery (by a different server instance in a cluster) is not possible if the failed instance used an
EMBEDDED
Message Queue broker, or if it used aLOCAL
orREMOTE
Message Queue broker and the broker also failed. In this case, only automatic recovery on server instance restart is possible. This is because for conventional Message Queue clustering, state information in a failed broker is not available until the broker restarts.
Oracle Setup for Transaction Recovery
You must configure the following grant
statements in your Oracle database to set up transaction recovery:
grant select on SYS.DBA_PENDING_TRANSACTIONS to user;
grant execute on SYS.DBMS_SYSTEM to user;
grant select on SYS.PENDING_TRANS$ to user;
grant select on SYS.DBA_2PC_NEIGHBORS to user;
grant execute on SYS.DBMS_XA to user;
grant select on SYS.DBA_2PC_PENDING to user;
The user is the database administrator. On some versions of the Oracle driver the last grant execute
fails. You can ignore this.
Oracle Thin Driver
In the Oracle thin driver, the XAResource.recover
method repeatedly returns the same set of in-doubt Xids regardless of the input flag.
According to the XA specifications, the Transaction Manager initially calls this method with TMSTARTSCAN and then with TMNOFLAGS repeatedly until no Xids are returned.
The XAResource.commit
method also has some issues.
To disable the Payara Server workaround, set the
oracle-xa-recovery-workaround
property value to false
. For details
about how to set this property, see Configuring the Transaction Service.
This workaround is used unless explicitly disabled.
Delegated Recovery After Server Crash Doesn’t Work on MySQL
The MySQL database supports XA transaction recovery only when the database crashes. When a Payara Server instance crashes, MySQL rolls back prepared transactions.
Call to XATeminator.recover()
During ResourceAdapter.start()
Hangs If Automatic Recovery Is Enabled
Calls to XATerminator.recover()
from the ResourceAdapter.start()
method never return because Payara Server deadlocks. This only occurs when automatic recovery is enabled.
It is not advisable to do transactional activities, such as starting a transaction or calling XATerminator.recover()
, during ResourceAdapter.start()
.
For more information, see http://markmail.org/message/ogc7qndhaywfkdrp#query:+page:1+mid:kyyzpcexusbnv7ri+state:results
.
Transaction Logging
The transaction service writes transactional activity into transaction logs so that transactions can be recovered. You can control transaction logging in these ways:
-
Set the location of the transaction log files in one of these ways:
-
Set the Payara Server’s
log-root
setting to a shared file system base directory and set the transaction service’stx-log-dir
attribute to a relative path. -
Set
tx-log-dir
to an absolute path to a shared file system directory, in which caselog-root
is ignored for transaction logs. -
Set a system property called
TX-LOG-DIR
to a shared file system directory. For example:
-
asadmin> create-system-properties --target server TX-LOG-DIR=/inst1/logs
For information about setting log-root
and other general logging settings,
see Administering the Logging Service.
-
Turn off transaction logging by setting the
disable-distributed-transaction-logging
property totrue
and theautomatic-recovery
attribute tofalse
. Do this only if performance is more important than transaction recovery.
All instances in a cluster must be owned by the same user (uid ), and read/write permissions for that user must be set on the transaction log directories.
|
Transaction logs should be stored in a high-availability network file system (NFS) to avoid a single point of failure.
To Store Transaction Logs in a Database
For multi-core machines, logging transactions to a database may be more efficient. Transaction logging is designed to work with any JDBC-compliant database. For databases with which transaction logging has been tested, see the Payara Server Release Notes.
-
Create a JDBC connection Pool. To use non-transactional connections to insert log records, you can either set the
non-transactional-connections
attribute totrue
in this step, or you can perform step 5 later. -
Create a JDBC resource that uses the connection pool and note the JNDI name of the JDBC resource.
-
Automatic table creation for the transaction logs is done by default. However, if you would prefer to create the table manually, name it
txn_log_table
with the following schema:Column Name
JDBC Type
LOCALTID
VARCHAR
INSTANCENAME
VARCHAR
SERVERNAME
VARCHAR(n)
GTRID
VARBINARY
The size of the
SERVERNAME
column should be at least the length of the Payara Server host name plus 10 characters.
The size of theGTRID
column should be at least 64 bytes. -
Add the
db-logging-resource
property to the transaction service. For example:asadmin set server-config.transaction-service.property.db-logging-resource="jdbc/TxnDS"
The property’s value should be the JNDI name of the JDBC resource configured previously.
-
If you didn’t set the
non-transactional-connections
attribute totrue
in step 1 and you want to use non-transactional connections to insert log records, use the followingasadmin create-jvm-options
command to reference an existingtransactional resource but use non-transactional connections for theINSERT
statements:asadmin create-jvm-options -Dcom.sun.jts.dblogging.use.nontx.connection.for.add=true
-
To disable file synchronization, use the following
asadmin create-jvm-options
command:asadmin create-jvm-options -Dcom.sun.appserv.transaction.nofdsync
-
Restart the server.
Next Steps
To define the SQL used by the transaction manager when it is storing its transaction logs in the database, use the following flags:
-Dcom.sun.jts.dblogging.insertquery=sql
statement
-Dcom.sun.jts.dblogging.deletequery=sql
statement
-Dcom.sun.jts.dblogging.selectquery=sql
statement
-Dcom.sun.jts.dblogging.selectservernamequery=sql
statement
The default statements are as follows:
-Dcom.sun.jts.dblogging.insertquery=insert into txn_log_table values ( ?, ?, ?, ? )
-Dcom.sun.jts.dblogging.deletequery=delete from txn_log_table where localtid = ? and servername = ?
-Dcom.sun.jts.dblogging.selectquery=select * from txn_log_table where servername = ?
-Dcom.sun.jts.dblogging.selectservernamequery=select distinct servername from txn_log_table where instancename = ?
To set one of these flags using the asadmin create-jvm-options
command, you must quote the statement. For example:
create-jvm-options '-Dcom.sun.jts.dblogging.deletequery=delete from txn_log_table where gtrid = ?'
You can also set JVM options in the Administration Console. Select the JVM Settings component under the relevant configuration. These flags and their statements must also be quoted in the Administration Console. For example:
'-Dcom.sun.jts.dblogging.deletequery=delete from txn_log_table where gtrid = ?'