Oracle8
Server Application Developer's Guide Release 8.0 A54642_01 |
|
This chapter describes how to use the Oracle XA library. The chapter includes the following topics:
For preliminary reading and additional reference information regarding the Oracle XA library, see the following documents:
Additional Information: For information on library linking filenames, see the Oracle operating system-specific documentation.
A README.doc file is located in a directory specified in the Oracle operating system-specific documentation and describes changes, bugs, or restrictions in the Oracle XA library for your platform since the last version.
The following changes have been made:
Session caching is unnecessary with the new OCI. Therefore, the old xa_open string parameter, SesCacheSz, has been eliminated. Consequently, you can also reduce the sessions init.ora parameter. Instead, set the transactions init.ora parameter to the expected number of concurrent global transactions. Because sessions are not migrated when global transactions are resumed, applications must not refer to any session state beyond the scope of a service. For information on how to organize your application into services, refer to the documentation provided with the transaction processing monitor. In particular, savepoints and cursor fetch state will be cancelled when a transaction is suspended. This means that a savepoint taken by the application in a service will be invalid in another service, even though the two services may belong to the same global transaction.
Dynamic registration can be used if, and only if, both the XA application and the Oracle Server are Version 8. See "Extensions to the XA Interface" on page 18-14 for further information.
The Oracle8 Server supports both loosely and tightly coupled transaction branches in a single Oracle instance. The Oracle7 Server supported only tightly coupled transaction branches in a single instance, and loosely coupled transaction branches in different instances.
OCI applications used to require the use of SQLLIB. This meant OCI programmers had to buy SQLLIB, even if they had no desire to develop Pro* applications. This is no longer the case.
The SQL script XAVIEW.SQL is not needed to run XA applications in Oracle Version 8. It is, however, still necessary for Version 7.3 applications. See "Responsibilities of the DBA or System Administrator" on page 18-16 for further information.
It was not possible with Version 7 to use the Oracle XA library together with the Oracle Parallel Server option on certain platforms. Only if the platform's implementation of the distributed lock manager supported transaction-based rather than process-based locking would the two work together. This limitation is no longer the case; if you can run the Oracle Parallel Server option, then you can run the Oracle XA library.
All transactions can be recovered from any instance of Oracle Parallel Server. Use the xa_recover call to provide a snapshot of the pending transactions.
It is now possible to have both global and local transactions within the same XA connection. Local transactions are transactions that are completely coordinated by the Oracle Server. For example, the update below belongs to a local transaction.
CONNECT SCOTT/TIGER; UPDATE EMP set sal = sal + 1; /* begin local transaction*/ COMMIT; /* commit local transaction*/
Global transactions, on the other hand, are coordinated by an external transaction manager such as a transaction processing monitor. In these transactions, the Oracle Server acts as a subordinate and processes the XA commands issued by the transaction manager. The update shown below belongs to a global transaction.
xa_open(oracle_xa+acc=p/SCOTT/TIGER+sestm=10", 1, TMNOFLAGS); /*Transaction manager opens */ /* connection to the Oracle server*/ tpbegin(); /*begin global transaction, the transaction*/ /*manager issues XA commands to the oracle*/ /*server to start a global transaction */ UPDATE EMP set sal = sal + 1; /* update is performed in the */ /* global transaction*/ tpcommit(); /* commit global transaction, */ /* the transaction manager issues XA commands*/ /* to the Oracle server to commit */ /* the global transaction */
The Oracle7 Server forbids a local transaction from being started in an XA connection. The update shown below would return an ORA-2041 error code.
xa_open("oracle_xa+acc=p/SCOTT/TIGER+sestm=10" , 1, TMNOFLAGS); /* Transaction manager opens */ /*connection to the Oracle server */ UPDATE EMP set sal = sal + 1; /* Oracle 7 returns an error */
The Oracle8 Server, on the other hand, allows local transactions to be started in an XA connection. The only restriction is that the local transaction must be ended (committed or rolled back) before starting a global transaction in the connection.
Additional Information: For more information on global transactions, see Programmer's Guide to the Oracle Call Interface, Volume I: OCI Concepts.
Two new parameters have been added. They are:
This parameter has a boolean value and should not be set to true when connected to an Oracle7 Server. If set to true, it indicates that global transaction branches will be loosely coupled, that is, locks will not be shared between branches.
This parameter's value indicates the time-out limit when waiting for a transaction branch that is being used by another session. If Oracle cannot switch to the transaction branch within SesWt seconds, XA_RETRY will be returned.
Two parameters have been made obsolete and should only be used when connected to an Oracle Server Release 7.3.
The group password is not used by Oracle8. A session that is logged in with the same user name as the session that created a transaction branch will be allowed to switch to the transaction branch.
This parameter is not used by Oracle8 because session caching has been eliminated.
Oracle XA applications can access other Oracle Server databases through database links, with the following restrictions:
This means the transaction processing monitors (TPMs) will use shared servers to open the connection to Oracle. The O/S network connection required for the database link will be opened by the dispatcher instead of the Oracle server process. Thus, when a particular service or RPC completes, the transaction can be detached from the server so that it can be used by other services or RPCs.
Assuming that these restrictions are satisfied, Oracle Server will allow such links and will propagate the transaction protocol (prepare, rollback, and commit) to the other Oracle Server databases.
Warning: If these restrictions are not satisfied, when you use database links within an XA transaction, it creates an O/S network connection in the Oracle Server that is connected to the TPM server process. Since this O/S network connection cannot be moved from one process to another, you cannot detach from this server. When you access a database through a database link, you will receive an ORA#24777 error.
If using the Multi-Threaded Server configuration is not possible then, access the remote database through the Pro*C/C++ application using EXEC SQL AT syntax.
The parameter open_links_per_instance specifies the number of migratable open database link connections. These dblink connections are used by XA transactions so that the connections are cached after a transaction is committed. Another transaction is free to use the dblink connection provided the user that created the connection is the same as the user who created the transaction. This parameter is different from the open_links parameter, which is the number of dblink connections from a session. The open_links parameter is not applicable to XA applications.
You can recover failed transactions from any instance of Oracle Parallel Server. You can also heuristically commit in-doubt transactions from any instance. An XA recover call will give a list of all prepared transactions for all instances.
SQL-based restrictions are listed in this section.
Because the transaction manager is responsible for coordinating and monitoring the progress of the global transaction, the application should not contain any Oracle Server-specific statement that independently rolls back or commits a global transaction. However, you can use rollbacks and commits in a local transaction.
Do not use EXEC SQL ROLLBACK WORK for precompiler applications when you are in the middle of a global transaction. Similarly, an OCI application should not execute OCITransRollback(), or the Version 7 equivalent orol(). You can roll back a global transaction by calling tx_rollback().
Similarly, a precompiler application should not have the EXEC SQL COMMIT WORK statement in the middle of a global transaction. An OCI application should not execute OCITransCommit() or the Version 7 equivalent ocom(). Instead, use tx_commit() or tx_rollback() to end a global transaction.
Because a DDL SQL statement such as CREATE TABLE implies an implicit commit, the Oracle XA application cannot execute any DDL SQL statements.
Oracle does not guarantee that session state will be valid between services. For example, if a service updates a session variable (such as a global package variable), another service that executes as part of the same global transaction may not see the change. Use savepoints only within a service. The application must not refer to a savepoint that was created in another service. Similarly, an application must not attempt to fetch from a cursor that was executed in another service.
Do not use the SET TRANSACTION READ ONLY | READ WRITE | USE ROLLBACK SEGMENT SQL statement.
Do not use the EXEC SQL command to connect or disconnect. That is, do not use EXEC SQL COMMIT WORK RELEASE or EXEC SQL ROLLBACK WORK RELEASE.
Note the following additional information about Oracle XA:
Oracle Server transaction branches within the same global transaction can share locks in either a tightly or loosely coupled manner. However, if the branches are on different instances when running Oracle Parallel Server, then they will be loosely coupled.
In tightly coupled transaction branches, the locks are shared between the transaction branches. This means that updates performed in one transaction branch can be seen in other branches that belong to the same global transaction before the update is committed. The Oracle Server obtains the DX lock before executing any statement in a tightly coupled branch. Hence, the advantage of using loosely coupled transaction branches is that there will be more concurrency(because a lock is not obtained before the statement is executed). The disadvantage is that all the transaction branches must go through the two phases of commit, that is, XA one phase optimization cannot be used. These trade-offs between tightly coupled branches and loosely coupled branches are illustrated in Table 18-1.
The Oracle Server does not support association migration (a means whereby a transaction manager may resume a suspended branch association in another branch).
The optional XA feature asynchronous XA calls is not supported.
Set the transactions init.ora parameter to the expected number of concurrent global transactions.
The parameter open_links_per_instance specifies the number of migratable open database link connections. These dblink connections are used by XA transactions so that the connections are cached after a transaction is committed.
See "Database Links" on page 18-6 for further information.
No scripts need be executed to use XA. It is necessary, however, to run the xaview.sql script to run Release 7.3 applications with the Oracle8 Server. Grant the SELECT privilege on SYS.DBA_PENDING_TRANSACTIONS to all users that connect to Oracle through the XA interface.
The XA library supplied with Release 7.3 can be used with a Release 8.0 Oracle Server. You must use the Release 7.2 XA library with a Release 7.2 Oracle Server. You can use the 8.0 library with a Release 7.3 Oracle Server. There is only one case of backward compatibility: an XA application that uses Release 8.0 OCI will work with a Release 7.3 Oracle Server, but only if you use sqlld2 and obtain an lda_def before executing SQL statements. Client applications must remember to convert the Version 7 LDA to a service handle using OCILdaToSvcCtx() after completing the OCI calls.
The Oracle XA library is an external interface that allows global transactions to be coordinated by a transaction manager other than the Oracle8 Server. This allows inclusion of non-Oracle8 Server entities called resource managers (RM) in distributed transactions.
The Oracle XA library conforms to the X/Open Distributed Transaction Processing (DTP) software architecture's XA interface specification.
Additional Information: For a general overview of XA, including basic architecture, see X/Open CAE Specification - Distributed Transaction Processing: The XA Specification.
You can obtain a copy of this document by requesting X/Open Document No. XO/CAE/91/300 or ISBN 1 872630 24 3 from:
X/Open Company, Ltd.
1010 El Camino Real, Suite 380
Menlo Park, CA 94025
U.S.A.
The X/Open DTP architecture defines a standard architecture or interface that allows multiple application programs to share resources, provided by multiple, and possibly different, resource managers. It coordinates the work between application programs and resource managers into global transactions.
Figure 18-1 illustrates a possible X/Open DTP model.
A resource manager (RM) controls a shared, recoverable resource that can be returned to a consistent state after a failure. For example, Oracle8 Server is an RM and uses its redo log and undo segments to return to a consistent state after a failure. An RM provides access to shared resources such as a database, file systems, printer servers, and so forth.
A transaction manager (TM) provides an application program interface (API) for specifying the boundaries of the transaction and manages the commit and recovery procedures.
Normally, Oracle8 Server acts as its own TM and manages its own commit and recovery. However, using a standards-based TM allows Oracle8 Server to cooperate with other heterogeneous RMs in a single transaction.
A TM is usually a component provided by a transaction processing monitor (TPM) vendor. The TM assigns identifiers to transactions, and monitors and coordinates their progress. It uses Oracle XA library subroutines to tell Oracle8 Server how to process the transaction, based on its knowledge of all RMs in the transaction. You can find a list of the XA subroutines and their descriptions later in this section.
An application program (AP) defines transaction boundaries and specifies actions that constitute a transaction. For example, an AP can be a precompiler or OCI program. The AP operates on the RM's resource through the RM's native interface, for example SQL. However, it starts and completes all transaction operations via the transaction manager through an interface called TX. The AP itself does not directly use the XA interface.
Note: The naming conventions for the TX interface and associated subroutines are vendor-specific, and may differ from those used here. For example, you may find that the tx_open call is referred to as tp_open on your system. To check terminology, see the documentation supplied with the transaction processing monitor.
The Oracle XA library interface follows the two-phase commit protocol, consisting of a prepare phase and a commit phase, to commit transactions.
In phase one, the prepare phase, the TM asks each RM to guarantee the ability to commit any part of the transaction. If this is possible, then the RM records its prepared state and replies affirmatively to the TM. If it is not possible, the RM may roll back any work, reply negatively to the TM, and forget any knowledge about the transaction. The protocol allows the application, or any RM, to roll back the transaction unilaterally until the prepare phase is complete.
In phase two, the commit phase, the TM records the commit decision. Then the TM issues a commit or rollback to all RMs which are participating in the transaction. Note that a TM can issue a commit for an RM only if all RMs have replied affirmatively to phase one.
The Oracle XA library subroutines allow a TM to instruct an Oracle8 Server what to do about transactions. Generally, the TM must "open" the resource (using xa_open). Typically, this will result from the AP's call to tx_open. Some TMs may call xa_open implicitly, when the application begins. Similarly, there is a close (using xa_close) that occurs when the application is finished with the resource. This may be when the AP calls tx_close or when the application terminates.
There are several other tasks the TM instructs the RMs to do. These include among others:
The following XA Library subroutines are available:
In general, the AP does not need to worry about these subroutines except to understand the role played by the xa_open string.
Two functions have been added to the XA interface, one for returning the OCI service handle associated with an XA connection, and one for returning an XA error code.
A transaction processing monitor (TPM) coordinates the flow of transaction requests between the client processes that issue requests and the back-end servers that process them. Basically, it coordinates transactions that require the services of several different types of back-end processes, such as application servers and resource managers that are distributed over a network.
The TPM synchronizes any commits and rollbacks required to complete a distributed transaction. The transaction manager (TM) portion of the TPM is responsible for controlling when distributed commits and rollbacks take place. Thus, if a distributed application program is written to take advantage of a TPM, the TM portion of the TPM is responsible for controlling the two-phase commit protocol. The RMs enable the TMs to do this.
Because the TM controls distributed commits or rollbacks, it must communicate directly with Oracle (or any other resource manager) through the Oracle XA library interface.
As a resource manager, Oracle is required to publish the following information.
xa_switch_t structures |
The Oracle Server xa_switch_t structure name for static registration is xaosw. The Oracle Server xa_switch_t structure name for dynamic registration is xaoswd. These structures contain entry points and other information for the resource manager. |
xa_switch_t resource mgr |
The Oracle Server resource manager name within the xa_switch_t structure is Oracle_XA. |
close string |
The close string used by xa_close () is ignored and is allowed to be null. |
open string |
The format of the open string used by xa_open () is described in detail in "Developing and Installing Applications that use the XA Libraries" on page 18-16. |
libraries |
|
requirements |
A purchased and installed distributed database option. |
Dynamic and static registration are supported by the Oracle8 Server. The basic possibilities are shown in Table 18-2.
Client | Server | XA Registration |
---|---|---|
8.0 XA application |
8.0 |
Dynamic |
8.0 XA application |
7.3 |
Static |
7.3 XA application |
8.0 |
Static |
This section discusses developing and installing Oracle8 Server applications. It describes the responsibilities of both the DBA, or system administrator, and the application developer. It also defines how to construct the open string.
The responsibilities of the DBA or system administrator are
This is described in "Defining the xa_open String" on page 18-17.
This view should have been created during the XA library installation. You can manually create the view if needed by running the SQL script XAVIEW.SQL. This SQL script should be executed as the Oracle user SYS. Grant the SELECT privilege to the V$XATRANS$ view for all Oracle Server accounts which will be used by Oracle XA library applications.
Additional Information: See your Oracle operating system-specific documentation for the location of the XAVIEW.SQL script.
Grant the select privilege to the DBA_PENDING_TRANSACTIONS view for all Oracle Server user(s) specified in the xa_open string.
The DBA or system administrator should be aware that a TPM system will start the process that connects to an Oracle8 Server. See your TPM documentation to determine what environment exists for the process and what user ID it will have.
Be sure that correct values are set for ORACLE_HOME
and ORACLE_SID.
Next, grant the user ID write permission to the directory in which the XA trace file will be written. See "Defining the xa_open String" on page 18-17 for information on how to specify a sid or a trace directory that is different from the defaults.
Also be sure to grant the user the SELECT privilege on DBA_PENDING_TRANSACTIONS.
This should be done before starting any TPM servers.
The application developer's responsibilities are
Defining the open string is described later in this section.
Observe special restrictions on transaction-oriented SQL statements for precompilers. See "Interfacing to Precompilers and OCIs" on page 18-22.
The open string is used by the transaction monitor to open the database. The maximum number of characters in an open string is 256.
This section covers:
Oracle_XA{+required_fields...} [+optional_fields...]
where required_fields are:
and where optional_fields are:
Note the following:
Required fields for the open string are described in this section.
Acc=P//
or
Acc=P/user/password
Acc |
Specifies user access information |
P |
Indicates that explicit user and password information is provided. |
P// |
Indicates that no explicit user or password information is provided and that the operating system authentication form will be used. For more information see Oracle8 Server Administrator's Guide. |
user |
A valid Oracle Server account. |
password |
The corresponding current password. |
For example, Acc=P/scott/tiger indicates that user and password information is provided. In this case, the user is scott and the password is tiger.
As previously mentioned, make sure that scott has the SELECT privilege on the DBA_PENDING_TRANSACTIONS table.
Acc=P// indicates that no user or password information is provided, thus defaulting to operating system authentication.
SesTm=session_time_limit
Optional fields are described below.
DB=db_name
For example, DB=payroll indicates that the database name is "payroll", and that the application server program will use that name in AT clauses.
LogDir=log_dir
For example, LogDir=/xa_trace indicates that the error and tracing information is located under the /xa_trace directory.
Note: Ensure that the directory you specify for logging exists and the application server can write to it.
MaxCur=maximum_#_of_open_cursors
For example, MaxCur=5 indicates that the precompiler should try to keep five open cursors cached.
Note: This parameter overrides the precompiler option maxopencursors that you might have specified in your source code or at compile time.
For more information on maxopencursors, see Chapter 8 in Programmer's Guide to the Oracle Pro*C/C++ Precompiler Release 3.0.
SqlNet=db_link
For example, SqlNet=hqfin@NEWDB indicates the database with sid=NEWDB accessed at host hqfin by TCP/IP.
The SqlNet parameter can be used to specify the ORACLE_SID in cases where you cannot control the server environment variable. It must also be used when the server needs to access more than one Oracle Server database. To use the Net8 string without actually accessing a remote database, use the Pipe driver.
For example:
SqlNet=localsid1
where:
localsid1 |
is an alias defined in the Net8 tnsnames.ora file. |
Make sure that all databases to be accessed with a Net8 database link have an entry in /etc/oratab.
Loose_Coupling=true/false
SesWt=session_wait_limit
Threads=true/false
Threads |
Specifies whether the application is multi-threaded. The default value is False. |
true/false |
If the application is multi-threaded, the setting is true. |
This section describes how to use the Oracle XA library with precompilers and Oracle Call Interfaces (OCIs).
When used in an Oracle XA application, cursors are valid only for the duration of the transaction. Explicit cursors should be opened after the transaction begins, and closed before the commit or rollback. Also, you must use the release_cursor=yes option when compiling a precompiler application.
There are two options to choose from when interfacing with precompilers:
The following examples use the precompiler Pro*C/C++.
To interface to a precompiler with the default database, make certain that the DB=db_name field, used in the open string, is not present. The absence of this field indicates the default connection, and only one default connection is allowed per process.
The following is an example of an open string identifying a default Pro*C/C++ connection.
ORACLE_XA+SqlNet=host@MAIL+ACC=P/scott/tiger +SesTM=10+LogDir=/usr/local/logs
Note that the DB=db_name is absent, indicating an empty database ID string.
The syntax of a SQL statement would be:
EXEC SQL UPDATE EMP SET SAL = sal*1.5;
To interface to a precompiler with a named database, include the DB=db_name field in the open string. Any database you refer to must reference the same db_name you specified in the corresponding open string.
An application may include the default database, as well as one or more named databases, as shown in the following examples.
For example, suppose you want to update an employee's salary in one database, his department number (DEPTNO) in another, and his manager in a third database. You would configure the following open strings in the transaction manager:
ORACLE_XA+DB=MANAGERS+SqlNet=hqfin@SID1+ACC=P/scott/tiger +SesTM=10+LogDir=/usr/local/xalog ORACLE_XA+DB=PAYROLL+SqlNet=SID2+ACC=P/scott/tiger +SesTM=10+LogDir=/usr/local/xalog ORACLE_XA+SqlNet=hqemp@SID3+ACC=P/scott/tiger +SesTM=10+LogDir=/usr/local/xalog
Note that there is no DB=db_name field in the last open string.
In the application server program, you would enter declarations such as:
EXEC SQL DECLARE PAYROLL DATABASE; EXEC SQL DECLARE MANAGERS DATABASE;
Again, the default connection (corresponding to the third open string that does not contain the db_name field) needs no declaration.
When doing the update, you would enter statements similar to the following:
EXEC SQL AT PAYROLL UPDATE EMP SET SAL=4500 WHERE EMPNO=7788; EXEC SQL AT MANAGERS UPDATE EMP SET MGR=7566 WHERE EMPNO=7788; EXEC SQL UPDATE EMP SET DEPTNO=30 WHERE EMPNO=7788;
There is no AT clause in the last statement because it is referring to the default database.
In Oracle precompilers Release 1.5.3 or later, you can use a character host variable in the AT clause, as the following example shows:
EXEC SQL BEGIN DECLARE SECTION; DB_NAME1 CHARACTER(10); DB_NAME2 CHARACTER(10); EXEC SQL END DECLARE SECTION; . . SET DB_NAME1 = 'PAYROLL' SET DB_NAME2 = 'MANAGERS' . . EXEC SQL AT :DB_NAME1 UPDATE... EXEC SQL AT :DB_NAME2 UPDATE...
Note: Oracle recommends against using XA applications to create connections. Any work performed would be outside the global transaction, and would have to be committed separately.
OCI applications that use the Oracle XA library should not call OCISessionBegin() (olon() or orlon() in Version 7) to log on to the resource manager. Rather, the logon should be done through the TPM. The applications can execute the function xaoSvcCtx() (sqlld2() in Version 7) to obtain the service context (lda in Version 7) structure they need to access the resource manager.
Because an application server can have multiple concurrent open Oracle Server resource managers, it should call the function xaoSvcCtx() with the correct arguments to obtain the correct service context.
For Release 7.3:
If DB=db_name is not present in the open string, then execute:
sqlld2(lda, NULL, 0);
to obtain the lda for this resource manager.
Alternatively, if DB=db_name is present in the open string, then execute:
sqlld2(lda, db_name, strlen(db_name));
to obtain the lda for this resource manager.
For Release 8.0:
If DB=db_name is not present in the open string, then execute:
xaoSvcCtx(NULL);
to obtain the xaoSvcCtx for this resource manager.
Alternatively, if DB=db_name is present in the open string, then execute:
xaoSvcCtx(db_name);
to obtain the OCISvcCtx for this resource manager.
Additional Information: For more information about using the OCISvcCtx, see the Programmer's Guide to the Oracle Call Interface, Volume I: OCI Concepts.
This section explains how to use transaction control within the Oracle XA library environment.
When the XA library is used, transactions are not controlled by the SQL statements which commit or roll back transactions. Rather, they are controlled by an API accepted by the TM which starts and stops transactions. Most of the TMs use the TX interface for this. It includes the following functions:
tx_open |
logs into the resource manager(s) |
tx_close |
logs out of the resource manager(s) |
tx_begin |
starts a new transaction |
tx_commit |
commits a transaction |
tx_rollback |
rolls back the transaction |
Most TPM applications are written using a client-server architecture where an application client requests services and an application server provides services. The examples that follow use such a client-server model. A service is a logical unit of work, which in the case of the Oracle Server as the resource manager, comprises a set of SQL statements that perform a related unit of work.
For example, when a service named "credit" receives an account number and the amount to be credited, it will execute SQL statements to update information in certain tables in the database. In addition, a service might request other services. For example, a "transfer fund" service might request services from a "credit" and "debit" service.
Usually application clients request services from the application servers to perform tasks within a transaction. However, for some TPM systems, the application client itself can offer its own local services.
You can encode transaction control statements within either the client or the server; as shown in the examples.
To have more than one process participating in the same transaction, the TPM provides a communication API that allows transaction information to flow between the participating processes. Examples of communications APIs include RPC, pseudo-RPC functions, and send/receive functions.
Because the leading vendors support different communication functions, the examples that follow use the communication pseudo-function tpm_service to generalize the communications API.
X/Open has included several alternative methods for providing communication functions in their preliminary specification. At least one of these alternatives is supported by each of the leading TPM vendors.
The following examples illustrate precompiler applications. Assume that the application servers have already logged onto the TPM system, in a TPM-specific manner.
The first example shows a transaction started by an application server, and the second example shows a transaction started by an application client.
Client:
tpm_service("ServiceName"); /*Request Service*/
Server:
ServiceName() { <get service specific data> tx_begin(); /* Begin transaction boundary*/ EXEC SQL UPDATE ....; /*This application server temporarily becomes*/ /*a client and requests another service.*/ tpm_service("AnotherService"); tx_commit(); /*Commit the transaction*/ <return service status back to the client> }
Client:
tx_begin(); /* Begin transaction boundary */ tpm_service("Service1"); tpm_service("Service2"); tx_commit(); /* Commit the transaction */
Server:
Service1() { <get service specific data> EXEC SQL UPDATE ....; <return service status back to the client> } Service2() { <get service specific data> EXEC SQL UPDATE ....; ... <return service status back to client> }
To migrate existing precompiler or OCI applications to a TPM application using the Oracle XA library, you must do the following:
This means that application clients request services from
application servers.
Some TPMs require the application to use the tx_open and tx_close functions, whereas other TPMs do the logon and logoff implicitly.
If you do not specify the sqlnet parameter in your open string, the application will use the default Net8 driver. Thus, you need to be sure that the application server is brought up with the ORACLE_HOME and ORACLE_SID environment variables properly defined. This is accomplished in a TPM-specific fashion. See your TPM vendor documentation for instructions on how to accomplish this.
For example, replace the connect statements EXEC SQL CONNECT (for precompilers) or OCISessionBegin() (for OCIs) by tx_open(). Replace the disconnect statements EXEC SQL COMMIT/ROLLBACK RELEASE WORK (for precompilers), or OCISessionEnd() (for OCIs) by tx_close(). The V7 equivalent for OCISessionBegin() was olon() and for OCISessionEnd(), ologof().
For example, replace the commit/rollback statements EXEC SQL COMMIT/ROLLBACK WORK (for precompilers), or ocom()/orol() (for OCIs) by tx_commit()/tx_rollback() and start the transaction by calling tx_begin().
Table 18-3 lists the TPM functions that replace regular Oracle commands when migrating precompiler or OCI applications to TPM applications.
If you use a transaction monitor that supports threads, the Oracle XA library allows you to write applications that are thread safe. Certain issues must be kept in mind, however.
A thread of control (or thread) refers to the set of connections to resource managers. In an unthreaded system, each process could be considered a thread of control, since each process has its own set of connections to resource managers and each process maintains its own independent resource manager table.
In a threaded system, each thread has an autonomous set of connections to resource managers and each thread maintains a private resource manager table. This private resource manager table must be allocated for each new thread and de-allocated when the thread terminates, even if the termination is abnormal.
Note that, in an Oracle system, once a thread has been started and establishes a connection, only that thread can use that connection. No other thread can make a call on that connection.
The xa_open string parameter, xa_info, provides the clause, Threads=, which must be specified as true to enable the use of threads by the transaction monitor. The default is false. Note that, in most cases, threads will be created by the transaction monitor and that the application will not know when a new thread is created. Therefore, it is advisable to allocate a service context (lda in Version 7) on the stack within each service that is written for a transaction monitor application. Before doing any Oracle-related calls in that service, the xaoSvcCtx (sqlld2 for Version 7 OCI) function must be called and the service context initialized. This LDA can then be used for all OCI calls within that service.
The following restrictions apply when using threads:
This section discusses how to find information in case of problems or system failure. It also discusses trace files and recovery of pending transactions.
The Oracle XA library logs any error and tracing information to its trace file. This information is useful in supplementing the XA error codes. For example, it can indicate whether an xa_open failure is caused by an incorrect open string, failure to find the Oracle Server instance, or a login authorization failure.
The name of the trace file is:
xa_db_namedate.trc
where db_name is the database name you specified in the open string field DB=db_name, and date is the date when the information is logged to the trace file.
If you do not specify DB=db_name in the open string, it automatically defaults to the name "NULL".
Normally, the XA trace file is opened only if an error is detected. The xa_open string DbgFl provides a tracing facility to record additional detail about the XA library. By default, its value is zero. It can be set to any combination of the following values. Note that they are independent, so to get printout from two or more flags, each must be set.
The trace file can be placed in one of the following locations:
Examples of two types of trace files are discussed below:
The example, xa_NULL040292.trc, shows a trace file that was created on April 2, 1992. Its DB field was not specified in the open string when the resource manager was opened.
The example, xa_Finance121591.trc, shows a trace file was created on December 15, 1991. Its DB field was specified as "Finance" in the open string when the resource manager was opened.
Note that multiple Oracle XA library resource managers with the same DB field and LogDir field in their open strings log all trace information that occurs on the same day to the same trace file.
Each entry in the trace file contains information that looks like this:
1032.12345.2: ORA-01017: invalid username/password; logon denied 1032.12345.2: xaolgn: XAER_INVAL; logon denied
where "1032" is the time when the information is logged, "12345" is the process ID (PID), "2" is the resource manager ID, xaolgn is the module name, XAER_INVAL was the error returned as specified in the XA standard, and ORA-1017 is the Oracle Server information that was returned.
In-doubt or pending transactions are transactions that have been prepared, but not yet committed to the database.
Generally, the transaction manager provided by the TPM system should resolve any failure and recovery of in-doubt or pending transactions. However, the DBA may have to override an in-doubt transaction in certain circumstances, such as when the in-doubt transaction is:
For more information about overriding in-doubt transactions in the circumstances described above, or about how to decide whether the in-doubt transaction should be committed or rolled back, see the TPM documentation.
There are four tables under the Oracle Server SYS account that contain transactions generated by regular Oracle Server applications and Oracle XA applications. They are DBA_PENDING_TRANSACTIONS, V$GLOBAL_TRANSACTIONS, DBA_2PC_PENDING and DBA_2PC_NEIGHBORS
For transactions generated by Oracle XA applications, the following column information applies specifically to the DBA_2PC_NEIGHBORS table.
Remember that the db_name is always specified as DB=db_name in the open string. If you do not specify this field in the open string, then the value of this column is NULLxa.oracle.com for transactions generated by Oracle XA applications.
For example, you could use the SQL statement below to obtain more information
about in-doubt transactions generated by Oracle
XA applications.
SELECT * FROM DBA_2PC_PENDING p, DBA_2PC_NEIGHBORS n WHERE p.LOCAL_TRAN_ID = n.LOCAL_TRAN_ID AND n.DBID = 'xa_orcl';
Alternatively, if you know the format ID used by the transaction processing monitor, you can use DBA_PENDING_TRANSACTIONS or V$GLOBAL_TRANSACTIONS. While DBA_PENDING_TRANSACTIONS gives a list of both active and failed prepared transactions, V$GLOBAL_TRANSACTIONS gives a list of all active global transactions.
|
Copyright © 1997 Oracle Corporation. All Rights Reserved. |
|