Oracle Services for Microsoft Transaction Server Developer's Guide Release 9.2 for Windows Part Number A95496-01 |
|
This chapter describes how to program with Microsoft Transaction Server and an Oracle database server.
This chapter contains these topics:
The focal point of the transaction process is a component of Microsoft Transaction Server called Microsoft Distributed Transaction Coordinator (MS DTC). When a client computer starts a business method on a transactional component, Microsoft Transaction Server begins a transaction coordinated by the MS DTC. The Oracle connection pooling layer enables the database server to act as a resource manager (RM) in the MS DTC-coordinated transaction. Figure 5-1 and Table 5-1 provide an overview of how these and other components perform a transaction.
Component | Major Responsibilities |
---|---|
Client computer connection |
|
Transactional application logic COM components |
|
Oracle ODBC Driver, OO4O, Oracle Provider for OLE DB, and OCI |
|
OCI connection pool |
Performs the following for transaction components: |
MS DTC (part of Microsoft Transaction Server) |
|
Database server |
Regardless of the application program interface (API) you use, OCI connection pooling is used in nearly all cases to coordinate a transaction. Review the following sections for information about how a transaction is registered and OCI connection pooling coordinates the transaction:
Application components that run in the Microsoft Transaction Server environment are created as dynamic link libraries (DLLs). Application components are registered with Microsoft Transaction Server using the Microsoft Transaction Server Explorer graphical user interface (GUI) tool. When you register the application component, you mark it as one of the types described in Table 5-2.
How you register an application component determines if it runs in a Microsoft Transaction Server-coordinated transaction. Table 5-3 describes this process.
Table 5-3 Running Components in a Microsoft Transaction Server TransactionIf the Application Component... | Then... |
---|---|
Runs in a Microsoft Transaction Server-coordinated transaction |
OCI connection pooling is always used and Microsoft Transaction Server and its MS DTC component coordinate the creation, startup, management, and commitment phases of the transaction. Microsoft Transaction Server ensures that all changes made by the component are committed if the transaction succeeds, or are aborted if the transaction fails. See Also: "Microsoft Transaction Server-Coordinated Component Transaction Overview" |
Does not run in a Microsoft Transaction Server-coordinated transaction |
The component runs in a Microsoft Transaction Server environment, but the database servers that it accesses may or may not take part in MS DTC-coordinated transactions. If the transaction is not MS DTC-coordinated, the client application must create, start, manage, and commit the transaction. OCI connection pooling may be used, depending upon the interface accessing the database server (such as Oracle Provider for OLE DB, Oracle ODBC Driver, OO4O, or others). See Also: "MS DTC-Coordinated Component Transaction Overview" |
This section describes how OCI connection pooling, Microsoft Transaction Server, and MS DTC operate with application components in a Microsoft Transaction Server-coordinated transaction environment.
OraMTSSvcGet()
to obtain a service context from the OCI connection pooling component.These actions return OCI service and environment handles to client applications.
OraMTSSvcRel()
to release the OCI pooling connection obtained at the beginning of the transaction.SetComplete
(to commit database operations) or SetAbort
(to abort database operations) on the Microsoft Transaction Server context object associated with the component.This section describes how OCI connection pooling, Microsoft Transaction Server, and MS DTC operate with application components not running in a Microsoft Transaction Server-coordinated transaction, but using MS DTC.
OCIServerAttach()
and OCISessionBegin()
). For these connections, the application calls OraMTSEnlCtxGet()
to associate the OCI service context with an Microsoft Transaction Server enlistment context.OraMTSSvcGet(..,..,ORAMTS_CFLG_NOIMPLICIT)
, and not yet released with OraMTSSvcRel()
OraMTSJoinTxn()
.OraMTSSvcEnlist()
.OraMTSSvcEnlist()
with a NULL
transaction reference to de-enlist from an MS DTC coordinated transaction. For nonpooled connections, OraMTSTxnJoin()
is invoked with a NULL
transaction reference to perform the de-enlistment.OraMTSSvcRel()
to release a pooled connection back to the pool. For nonpooled connections, the client calls OraMTSEnlCtxRel()
to release the enlistment context and then logs off the database.pTransaction->Commit()
or pTransaction->Abort()
).The following OCI functions enable you to integrate the OCI client application with Microsoft Transaction Server and a database server. Review the following sections for information about this integration:
You must use OCI release 8.1 or higher. OCI releases earlier than 8.1 are not supported.
The only code change to make is in obtaining and releasing the OCI service context handle. An OCI service context handle and environment handle are acquired when you obtain a pooled OCI connection to the database with the OCI function OraMTSSvcGet()
. Include the oramts.h
header and link with the oramts.lib
library. When you are finished, call OCI function OraMTSSvcRel()
to release the service context handle and environment handle. Using OraMTSSvcGet()
enables you to receive connection pooling and implicit transaction support (if you registered the application component to run in a Microsoft Transaction Server transaction). See "OraMTSSvcGet() Function" and "OraMTSSvcRel() Function" for more information.
In releases prior to 9.0, OraMTSSvcEnlist()
and OraMTSSvcEnlistEx()
enlisted nonpooled OCI connections in Microsoft Transaction Server transactions. This is no longer supported. These functions are still available to enlist pooled connections in MS DTC-coordinated transactions. To enlist nonpooled OCI connections in Microsoft Transaction Server-started and MS DTC-coordinated transactions, the client must use OraMTSJoinTxn()
. See "OraMTSJoinTxn() Function" for more information.
Ensure that for each process, you call OCIInitialize
at least once before executing any other OCI calls. This initializes the OCI process environment. In addition, you must pass it the OCI_THREADED
flag. If you are using Microsoft's Internet Information Server (IIS) and the components are being called as in-process libraries, then OCIInitialize
is already called for you.
#include <oci.h> #include <oramts.h> #include <xolehlp.h> // other MTS relevant includes ... // prototype for the error handler. BOOL Chekerr(sword swOCIStat, OCIError *OCIErrh); // MTS component method HRESULT OCITestMethod() { IObjectContext *pObjectContext = NULL; OCIEnv *myenvh = NULL; OCISvcCtx *mysvch = NULL; OCIError *myerrh = NULL; OCIStnt *mystmh = NULL; DWORD dwStat; HRESULT hRes = S_OK; sword swOCIStat; BOOL bCommit = FALSE; char *lpzStmt = "UPDATE EMP SET SAL = SAL + 1000"; // Initialize the OCI environment first -- request OCI_THREADED OCIInitialize(OCI_THREADED, (dvoid*)NULL,NULL,NULL,NULL); // attempt to get a connection to the database through the resource dispenser OraMTSSvcGet( "scott","tiger","finprod_db",&mysvch, &myenvh, ORAMTS_CFLG_ALLDEFAULT); // validate return status if(dwStat != ORAMTS_ERR_NOERROR) { printf("error: failed to obtain a connection to the database - %ld", dwStat); goto cleanup; } // successful logon and enlistment in the MTS transaction. allocate statement // handles and other handles using the OCI environment handle myenvh .... swOCIStat = OCIHandleAlloc(myenvh, (void *)&myerrh,OCI_HTYPE_ERROR, 0 , NULL); if (Checkerr(swOCIStat, myerrh)) goto cleanup; swOCIStat = OCIHandleAlloc(myenvh, (dvoid *)&mystmh,OCI_HTYPE_STMT, 0,NULL); if (Checkerr(swOCIStat, myerrh)) goto cleanup; // prepare a DML statement OCIStmtPrepare(mystmh, myerrh, lpzStmt, lstrlen(lpzStmt), OCI_NTV_SYNTAX, OCI_DEFAULT) Checkerr(swOCIStat, myerrh); // execute the statement -- ensure that AUTOCOMMIT is not requested. OCIStmtExecute(mysvch, mystmh, myerrh, 1, 0, NULL, NULL, OCI_DEFAULT); if (Checkerr(swOCIStat, myerrh)) goto cleanup; // all's well so far choose to go for a commit bCommit = TRUE; cleanup: if (mystmh) OCIHandleFree((void*)mystmh, OCI_HTYPE_STMT); if (myerrh OCIHandleFree((void*)myerrh, OCI_HTYPE_ERROR); if (mysvch) OraMTSSvcRel(mysvch); if (bCommit) pObjectContext->SetComplete(); else pObjectContext->Abort(); return(bCommit ? S_OK : E_FAIL); }
See Also:
The files in the |
Figure 5-2 provides a high-level overview of how to use the OCI functions OraMTSSvcGet()
, OraMTSSvcRel()
, and OraMTSJoinTxn
.
COM applications not hosted by the Microsoft Transaction Server environment (also known as standalone applications) can also use methods 2, 3, and 4 in Figure 5-2. However, these application types cannot use declarative transactions (through the Microsoft Transaction Server Explorer Microsoft Management Console snap-in).
OraMTSSvcGet()
obtains a pooled connection (also known as an OCI service context) from the OCI connection pool. The pooled connection includes an OCI service context handle and OCI environment handle.
DWORD OraMTSSvcGet( text* lpUname, text* lpPsswd, text* lpDbnam, OCISvcCtx** pOCISvc, OCIEnv** pOCIEnv, ub4 dwConFlgs );
Table 5-4 describes the OraMTSSvcGet()
parameters.
Datatype | Parameter | Description |
---|---|---|
|
|
Username for connecting to the database server |
|
|
Password for the username |
|
|
The net service name for connecting to the database (created with Oracle Net Manager or Oracle Net Configuration Assistant) |
|
|
Pointer to the OCI service context handle |
|
|
Pointer to the OCI environment handle |
|
|
Connection flags, for which there are the following possible values: |
- |
- |
|
- |
- |
|
- |
- |
|
- |
- |
|
- |
- |
|
- |
- |
Returns ORAMTSERR_NOERROR
upon successful acquisition of an OCI pooling connection (OCI service context).
OraMTSSvcGet()
returns a pooled OCI connection to the caller, enabling a database transaction using OCI to begin. Use OraMTSSvcGet()
to implicitly enlist the OCI connection in a transaction coordinated by Microsoft Transaction Server. In this type of transaction, Microsoft Transaction Server controls the creation, startup, management, and commitment phases of the transaction through its MS DTC component.
OraMTSSvcGet()
also provides connection pooling without enlisting the database server in a Microsoft Transaction Server transaction. This is done by setting OraMTSSvcGet()
as follows:
OraMTSSvcGet(...,ORAMTS_CFLG_NOIMPLICIT)
In all cases where OraMTSSvcGet()
is used, you must always use OraMTSSvcRel()
to release the connection when finished.
Note: Connection pooling is used regardless of whether you enlist or do not enlist the COM component in a transaction. |
Use the flags ORAMTS_CFLG_SYSDBALOGN
and ORAMTS_CFLG_SYSOPRLOGN
when connecting as SYSDBA
and SYSOPER
, respectively.
To obtain a nonenlisted connection using the scott
/tiger
account, call OraMTSSvcGet()
as follows:
OraMTSSvcGet("SCOTT", "TIGER", "oracle", &OCISvc, &OCIEnv, ORAMTS_CFLG_ ALLDEFAULT | ORAMTS_CFLG_NOIMPLICIT);
OraMTSSvcGet()
does not support placing the username (lpUname
), password (lpPsswd
), and net service name syntax (lpDbname
) together in the username argument (for example, scott/tiger@prod_fin
). Instead, the caller must fill in lpUname
, lpPsswd
, and lpDbname
separately (as shown in the previous syntax example). Calling OraMTSSvcGet()
with the username and password as NULL
strings uses external authentication (operating system authentication) for the connection.
OraMTSSvcRel()
releases a pooled OCI connection (OCI service context) back to the connection pool. Use OraMTSSvcRel()
to release connections that were acquired with OraMTSSvcGet()
.
DWORD OraMTSSvcRel(OCISvcCtx* OCISvc);
Table 5-5 describes the OraMTSSvcRel()
parameters.
Datatype | Parameter | Description |
---|---|---|
|
|
OCI service context for a pooled connection |
Returns ORAMTSERR_NOERROR
upon successful release of a pooled OCI connection.
An OCI pooled connection obtained through a previous call to OraMTSSvcGet()
is released back to the connection pool. Once released back to the connection pool, the OCI service context, its environment handle, and all child handles are invalid.
A nontransactional client component must explicitly call OCITransCommit()
or OCITransAbort()
prior to releasing a connection obtained through OraMTSSvcGet(...,...,ORAMTS_CFLG_ALLDEFAULT)
back to the pool. Otherwise, all changes made in that session are rolled back. A transaction component uses the SetComplete
or SetAbort
methods on its Microsoft Transaction Server object context.
Components that have called OraMTSSvcGet(...,...,ORAMTS_CFLG_NOIMPLICIT)
to obtain a connection resource must first de-enlist the resource if enlisted. If the connection was enlisted explicitly, pTransaction->Commit()
or pTransaction->Abort()
must be called. Otherwise, OCITransCommit()
or OCITransAbort()
must be called before releasing the connection back to the pool.
OraMTSSvcEnlist()
enlists or de-enlists an OCI connection in a transaction coordinated by MS DTC. Use this call to explicitly enlist pooled connections. Nonpooled connections must enlist with OraMTSJoinTxn()
.
DWORD OraMTSSvcEnlist( OCISvcCtx* OCISvc, OCIError* OCIErr, void* lpTrans, unsigned dwFlags );
Table 5-6 describes the OraMTSSvcEnlist()
parameters.
Returns ORAMTSERR_NOERROR
on success.
Use this call to explicitly enlist or de-enlist a pooled connection. For enlisting and de-enlisting nonpooled connections, use OraMTSSvcRel()
.
OraMTSSvcEnlist()
enlists (or de-enlists) pooled OCI connections obtained previously through OraMTSSvcGet()
with the ORAMTS_CFLG_NOIMPLICIT
flag and not yet released with OraMTSSvcRel()
. The pooled OCI connections must be explicitly enlistable. When the transaction is complete, you must de-enlist OraMTSSvcEnlist()
, passing NULL
as the transaction pointer as follows:
OraMTSSvcEnlist (OCISvc, OCIErr, NULL, ORAMTS_ENFLG_DEFAULT)
You must use OraMTSSvcRel()
to release the connection when done.
Callers must:
OraMTSSvcEnlistEx()
enlists an OCI connection or service context in an MS DTC transaction. Use this call only to explicitly enlist pooled connections. Nonpooled connections must enlist with OraMTSJoinTxn()
.
DWORD OraMTSSvcEnlistEx( OCISvcCtx* OCISvc, OCIError* OCIErr, void* lpTrans, unsigned dwFlags, char* lpDBName );
Table 5-7 describes the OraMTSSvcEnlistEx()
parameters.
Returns ORAMTSERR_ILLEGAL_OPER
.
Use OraMTSSvcEnlistEx()
for pooled connections or OraMTSJoinTxn()
for nonpooled connections.
OraMTSEnlCtxGet()
creates an enlistment context for a nonpooled OCI connection.
DWORD OraMTSEnlCtxGet( text* lpUname, text* lpPsswd, text* lpDbnam, OCISvcCtx* pOCISvc, OCIError* pOCIErr, ub4 dwFlags, void** pCtxt );
Table 5-8 describes the OraMTSEnlCtxGet()
parameters.
Returns ORAMTSERR_NOERROR
on success.
This call sets up an enlistment context for a nonpooled connection. This call must be started just after the caller establishes the OCI connection to the database. Once created, this context can be passed into OraMTSJoinTxn()
calls. Prior to deleting the OCI connection, OraMTSEnlCtxRel()
must be called to delete the enlistment context.
Callers must:
OraMTSEnlCtxGet()
.OraMTSJoinTxn()
.OraMTSJoinTxn()
with a NULL
transaction pointer.OraMTSEnlCtxRel()
.OraMTSEnlCtxRel()
eliminates a previously set up enlistment context for a nonpooled OCI connection.
DWORD OraMTSEnlCtxRel(void* pCtxt);
Table 5-9 describes the OraMTSEnlCtxRel()
parameters.
Datatype | Parameter | Description |
---|---|---|
|
|
Enlistment context to eliminate |
Returns ORAMTSERR_NOERROR
on success.
Before dropping a nonpooled OCI connection, a client must call OraMTSEnlCtxRel()
to eliminate any enlistment context it may have created for that connection. The enlistment context can maintain OCI handles allocated off the connection's OCI environment handle. This makes it imperative that the environment handle is not deleted for the associated enlistment context.
OraMTSJoinTxn()
enlists a nonpooled OCI connection in an MS DTC transaction.
DWORD OraMTSJoinTxn(void* pCtxt, void* pTrans);
Table 5-10 describes the OraMTSJoinTxn()
parameters.
Datatype | Parameter | Description |
---|---|---|
|
|
Enlistment context for the OCI connection |
|
|
Reference to the MS DTC transaction object |
Returns ORAMTSERR_NOERROR
on success.
Clients use this call with nonpooled OCI connections to enlist connections in MS DTC-coordinated transactions. The client passes in the wide reference to the enlistment context representing the OCI connection, along with a reference to an MS DTC transaction object. If pTrans
is NULL
, the OCI connection is de-enlisted from any MS DTC transaction in which it is currently enlisted. You can enlist a previously-enlisted OCI connection in a different MS DTC transaction.
OraMTSTransTest()
tests if you are running inside a Microsoft Transaction Server-started transaction.
BOOL OraMTSTransTest();
None.
Returns true
if running inside a Microsoft Transaction Server transaction. Otherwise, false
is returned.
Microsoft Transaction Server transactional components use OraMTSTransTest()
to check if a component is running within the context of a Microsoft Transaction Server transaction. Note that this call can only test Microsoft Transaction Server-started transactions. Transactions started by directly calling the MS DTC are not detected.
OraMTSOCIErrGet()
retrieves the OCI error code and message text (if any) from the last OraMTS
function operation, typically OraMTSSvcGet()
or OraMTSJoinTxn()
.
BOOL OraMTSOCIErrGet(DWORD* dwErr, LPCHAR lpcEMsg, DWORD* lpdLen);
Table 5-11 describes the OraMTSOCIErrGet()
parameters.
Datatype | Parameter | Description |
---|---|---|
|
|
Error code |
|
|
Buffer for the error message, if any |
|
|
Set to the actual number of message bytes |
Returns true
if an OCI error is encountered. Otherwise, false
is returned. If true
is returned and lpcEMsg
and lpdLen
are valid, and there is a stashed error message, up to lpdLen
bytes are copied into lpcEMsg
. lpdLen
is set to the actual number of message bytes.
OraMTSOCIErrGet()
retrieves the OCI error code and OCI error message text, if any, from the last OraMTSSvc
operation on this thread. For example:
DWORD dwStat = OraMTSSvcGet("scott", "invalid_password","fin_prod", db",&mysvch, &myenvh, ORAMTS_CFLG_ALLDEFAULT); if (dwStat != ORAMTS_ERR_NOERROR) { DWORD dwOCIErr; char errBuf[MAX_PATH]; DWORD errBufLen = sizeof(effBuf); if (OraMTSOCIErrGet(&dwOCIErr, &errBuf, &errBufLen)) printf("OCIError %d: %s"\n); }
This section describes how to use Oracle ODBC Driver with Microsoft Transaction Server and a database server. Specific topics discussed are:
OCI connection pooling operates as described in "Microsoft Transaction Server Application Development Overview", with no changes to OCI code required for ODBC to operate.
To use Microsoft Transaction Server with either Oracle ODBC Driver 9.2 or Microsoft's Oracle ODBC driver, you must set the connection attribute. Use the function SQLSetConnectAttr
to call the parameter SQL_ATTR_ENLIST_IN_DTC
in the ODBC code. This enables you to receive connection pooling and implicit transaction support. See "Setting Up MTS to Access Oracle" in the Microsoft Transaction Server online Help for instructions.
The ODBC Driver Manager distributed with ODBC 3.0 is a Resource Dispenser that supports connection pooling. (See the Microsoft Transaction Server SDK for information.) Oracle ODBC Driver release 9.2 integrates with the ODBC 3.0 Driver Manager by supporting the SQLSetConnectAttr(...,..., SQL_ATTR_ENLIST_IN_DTC)
call to enlist or de-enlist the ODBC connection in or from MS DTC-coordinated transactions.
Use the Oracle ODBC Driver 9.2 with:
To configure Oracle ODBC Driver 9.2:
The Control Panel window appears.
The ODBC Data Source Administrator dialog box appears.
mtssamples.dsn
file. This file is located in ROOTDRIVE
:\program files\common files\odbc\data sources
.mtssamples.dsn
and click Remove.This deletes the configuration file that enables the Microsoft Transaction Server sample application demo to use Microsoft's ODBC driver.
The Create New Data Source wizard appears.
SERVER=database_alias USERNAME=scott PASSWORD=tiger
The following table describes the keywords and values.
If Using Oracle's ODBC For... | Then Enter... |
---|---|
Microsoft's sample application |
|
Applications you develop |
Any appropriate name |
If the database server release is 8.0.5 or earlier, you cannot use the integration information described in this guide. However, there is a solution if you use Microsoft's Oracle ODBC driver. No other APIs are supported.
You can use Microsoft's Oracle ODBC Driver included in Windows NT Option Pack 4 to enable applications to interact with Microsoft Transaction Server and a database server. If you use this driver, the rest of the information in this guide does not apply and you do not receive the following:
See "Setting Up MTS to Access Oracle" in the Microsoft Transaction Server online Help for instructions on enabling Microsoft's Oracle ODBC Driver. After following those instructions, perform these additional steps:
To configure Microsoft's Oracle ODBC Driver:
ORACLE_BASE
\
ORACLE_HOME
\oramts\samples\ sql\omtssamp.sql
script.mtssamples.dsn
file uses.HKEY_LOCAL_MACHINE\ SOFTWARE\ORACLE
:ORAOCI = ORA73.DLL
There are no special requirements for using OO4O. You must use release 8.1 or higher of OO4O. See the OO4O online Help file for additional information about using OO4O with Microsoft Transaction Server.
See Also:
"Microsoft Transaction Server Application Development Overview" for information about how connection pooling operates (with no changes required to the OO4O code) |
See the Oracle Provider for OLE DB Developer's Guide for information about using Oracle Provider for OLE DB with Microsoft Transaction Server.
Other APIs are not currently supported, unless they use Oracle's ODBC Driver 8.1 or higher, such as ActiveX Data Objects.
|
Copyright © 1996, 2002 Oracle Corporation. All Rights Reserved. |
|