|Oracle8i JDBC Developer's Guide and Reference
Release 3 (8.1.7)
Part Number A83724-01
Transactions manage changes to multiple databases within a single application as a unit of work. That is, if you have an application that manages data within one or more databases, you can ensure that all changes in all databases are committed at the same time if they are managed within a transaction.
Transactions are described in terms of ACID properties, which are as follows:
The JTA implementation, specified by Sun Microsystems, relies heavily on the JDBC 2.0 specification and XA architecture. The result is a complex requirement on applications in order to ensure that the transaction is managed completely across all databases. Sun Microsystems's specifies Java Transaction API (JTA) 1.0.1 and JDBC 2.0 on
You should be aware of the following when using JTA within the Oracle8i environment:
Whenever your application connected to a database using JDBC or a SQL server, you were creating a transaction. However, the transaction involved only the single database and all updates made to the database were committed at the end of these changes. This is referred to as a local transaction.
A global transaction involves a complicated set of management objects--objects that track all of the objects and databases involved in the transaction. These global transaction objects--
Transaction--track all objects and resources involved in the global transaction. At the end of the transaction, the
Transaction objects ensure that all database changes are atomically committed at the same time.
A transaction is said to be demarcated, which means that each transaction has a definite beginning and end point. For example, in an interactive tool such as SQL*Plus, a transaction is started with the SQL BEGIN statements. Then, each SQL DML statement is part of the transaction. A transaction ends when a SQL COMMIT or ROLLBACK statement is issued.
For JTA, transactions are demarcated programmatically through the
UserTransaction object, which must be bound within the namespace. The client or server starts the transaction by invoking the
UserTransaction.begin method; it ends the transaction by invoking either the
Each resource, including databases, that you want managed in the global transaction must be enlisted. The Oracle8i JTA implementation enlists all databases where the JDBC connection is opened through the
getConnection method of a JTA
DataSource. You must bind any
DataSource object to be used within a JTA transaction with the -
jta option of the
bindds command. This binds an Oracle-specific JTA
DataSource within the namespace. You cannot use any other type of
DataSource for global transactions.
Secondly, you must retrieve the connection within the context of a global transaction; that is, retrieve the connection after the
begin method of the
JTA automatically enlists a database resource through a
DataSource object: An object--client or server object--opens a JDBC connection to a remote database through the
DataSource object within the context of a global transaction. The client can open connections to remote databases through any client JDBC driver. Server objects can only open connections to databases through either a JDBC KPRB driver or a JDBC server-side Thin driver.
The enlistment of both the default and remote databases depends on an open global transaction context when the database connection is opened. That is, you must retrieve the database connection through the
DataSource.getConnection method after the
UserTransaction.begin method has been invoked. Figure 17-1 demonstrates this concept:
If your transaction involves more than one database, you must specify an Oracle8i database as the two-phase commit engine. See "Configuring Two-Phase Commit Engine" for more information.
One of the primary advantages for a global transaction is the number database resources managed as a single unit within the transaction. If your global transaction involves more than one database resource, you must specify a two-phase commit engine, which is an Oracle8i database designated to manage the changes to all databases within the transaction. The two-phase commit engine is responsible for ensuring that when the transaction ends, all changes to all databases are either totally committed or fully rolled back.
The two-phase commit engine can be a database outside or included within the transaction. The database that you choose to be the two-phase commit engine must be configured before the transaction begins. See "Configuring Two-Phase Commit Engine" for a full explanation of the two-phase commit engine setup.
Figure 17-2 shows two databases enlisted in the transaction and another database that is designated as the two-phase commit engine. Databases A and B are enlisted when a JDBC connection is opened, within a global transaction, to each database. The two-phase commit engine must be identified within the
UserTransaction object and database links from the two-phase commit engine to each database involved in the transaction must be created. See "Configuring Two-Phase Commit Engine" on how to perform this setup.
When the global transaction ends, the two-phase commit engine ensures that all changes made to the databases A and B are committed or rolled back simultaneously.
The following are the portions of the JTA specification that Oracle8i does not support.
Nested transactions are not supported in this release. If you attempt to begin a new transaction before committing or rolling back any existing transaction, the transaction service throws a
The transaction services supplied with this release do not interoperate with other JTA implementations.