The Java EE platform provides several abstractions that simplify development of dependable transaction processing for applications. This chapter discusses Java EE transactions and transaction support in the Sun GlassFish Enterprise Server.
This chapter contains the following sections:
For more information about the JavaTM Transaction API (JTA) and Java Transaction Service (JTS), see Chapter 12, Transactions, in Sun GlassFish Enterprise Server v2.1.1 Administration Guide and the following sites: http://java.sun.com/products/jta/ and http://java.sun.com/products/jts/.
You might also want to read “Chapter 35: Transactions” in the Java EE 5 Tutorial.
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.
The Enterprise Server supports a variety of JDBC XA drivers. For a list of the JDBC drivers currently supported by the Enterprise Server, see the Sun GlassFish Enterprise Server v2.1.1 Release Notes. For configurations of supported and other drivers, see Configurations for Specific JDBC Drivers in Sun GlassFish Enterprise Server v2.1.1 Administration Guide.
Java Message Service (JMS) Providers - Use of transactions ensures that messages are reliably delivered. The Enterprise Server is integrated with Sun GlassFish Message Queue, a fully capable JMS provider. For more information about transactions and the JMS API, see Chapter 18, Using the Java Message Service.
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 Chapter 12, Developing Connectors.
For details about how transaction resource managers, the transaction service, and applications interact, see Chapter 12, Transactions, in Sun GlassFish Enterprise Server v2.1.1 Administration Guide.
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 Java EE application.
In the Enterprise Server, a JDBC resource is non-XA if it meets any of the following criteria:
In the JDBC connection pool configuration, the DataSource class does not implement the javax.sql.XADataSource interface.
The Global Transaction Support box is not checked, or the Resource Type setting does not exist or 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.
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 resourced 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.
Some topics in the documentation pertain to features that are available only in domains that are configured to support clusters. Examples of domains that support clusters are domains that are created with the cluster profile or the enterprise profile. For information about profiles, see Usage Profiles in Sun GlassFish Enterprise Server v2.1.1 Administration Guide.
To enable cluster-wide automatic recovery, you must first facilitate storing of transaction logs in a shared file system. You can do this in one of these ways:
Set the Enterprise Server's log-root attribute to a shared file system base directory and set the transaction service's tx-log-dir attribute to a relative path.
Set tx-log-dir to an absolute path to a shared file system directory, in which case log-root is ignored for transaction logs.
Set a system-property called TX-LOG-DIR in the domain.xml file to a shared file system directory.
<server config-ref="server-config" name="server"> <system-property name="TX-LOG-DIR" value="/net/tulsa/nodeagents/na/instance1/logs" /> </server>
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. For information about setting log-root and other general logging settings, see Chapter 17, Configuring Logging, in Sun GlassFish Enterprise Server v2.1.1 Administration Guide. For information about system-property and the domain.xml file, see the Sun GlassFish Enterprise Server v2.1.1 Administration Reference.
You can configure the transaction service in the Enterprise Server in the following ways:
To configure the transaction service using the Admin Console, open the Transaction Service component under the relevant configuration. For details, click the Help button in the Admin Console.
To configure the transaction service, use the asadmin set command to set the following attributes.
server.transaction-service.automatic-recovery = false server.transaction-service.heuristic-decision = rollback server.transaction-service.keypoint-interval = 2048 server.transaction-service.retry-timeout-in-seconds = 600 server.transaction-service.timeout-in-seconds = 0 server.transaction-service.tx-log-dir = domain-dir/logs
You can also set these properties:
server.transaction-service.property.oracle-xa-recovery-workaround = false server.transaction-service.property.disable-distributed-transaction-logging = false server.transaction-service.property.xaresource-txn-timeout = 600 server.transaction-service.property.pending-txn-cleanup-interval = 60 server.transaction-service.property.use-last-agent-optimization = true server.transaction-service.property.db-logging-resource = jdbc/TxnDS server.transaction-service.property.delegated-recovery = false server.transaction-service.property.wait-time-before-recovery-insec = 60 server.transaction-service.property.xa-servername = myserver
You can use the asadmin get command to list all the transaction service attributes and properties. For details, see the Sun GlassFish Enterprise Server v2.1.1 Reference Manual.
You can access the Enterprise Server transaction manager, a javax.transaction.TransactionManager implementation, using the JNDI subcontext java:comp/TransactionManager or java:appserver/TransactionManager. You can access the Enterprise Server transaction synchronization registry, a javax.transaction.TransactionSynchronizationRegistry implementation, using the JNDI subcontext java:comp/TransactionSynchronizationRegistry or java:appserver/TransactionSynchronizationRegistry. You can also request injection of a TransactionManager or TransactionSynchronizationRegistry object using the @Resource annotation. Accessing the transaction synchronization registry is recommended. For details, see Java Specification Request (JSR) 907.
You can also access java:comp/UserTransaction.
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 using the Transaction Log Location setting in the Admin Console, or set the tx-log-dir attribute using the asadmin set command.
Turn off transaction logging by setting the disable-distributed-transaction-logging property to true and the automatic-recovery attribute to false. Do this only if performance is more important than transaction recovery.
For multi-core machines, logging transactions to a database may be more efficient.
To log transactions to a database, follow these steps:
Create a JDBC connection Pool, and set the non-transactional-connections attribute to true.
Create a JDBC resource that uses the connection pool and note the JNDI name of the JDBC resource.
Create a table named txn_log_table with the schema shown in Table 16–1.
Add the db-logging-resource property to the transaction service. For example:
asadmin set --user adminuser server1.transaction-service.property.db-logging-resource="jdbc/TxnDS" |
The property's value should be the JNDI name of the JDBC resource configured previously.
To disable file synchronization, use the following asadmin create-jvm-options command:
asadmin create-jvm-options --user adminuser -Dcom.sun.appserv.transaction.nofdsync |
Restart the server.
For information about JDBC connection pools and resources, see Chapter 15, Using the JDBC API for Database Access. For more information about the asadmin create-jvm-options command, see the Sun GlassFish Enterprise Server v2.1.1 Reference Manual.
Table 16–1 Schema for txn_log_table
Column Name |
JDBC Type |
---|---|
LOCALTID |
BIGINT |
SERVERNAME |
VARCHAR(n) |
GTRID |
VARBINARY |
The size of the SERVERNAME column should be at least the length of the Enterprise Server host name plus 10 characters.
The size of the GTRID column should be at least 64 bytes.
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
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 = ?
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 Admin Console. In the developer profile, select the Application Server component and the JVM Settings tab. In the cluster profile, select the JVM Settings component under the relevant configuration. These flags and their statements must also be quoted in the Admin Console. For example:
'-Dcom.sun.jts.dblogging.deletequery=delete from txn_log_table where gtrid = ?'
The Enterprise Server provides workarounds for some known issues with the recovery implementations of the following JDBC drivers. These workarounds are used unless explicitly disabled.
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 Enterprise 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.
These workarounds do not imply support for any particular JDBC driver.