Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
Home -> Community -> Usenet -> c.d.o.server -> Re: Seeking Testing Volunteers W2K MTS/DTC to VMS DECdtm Distributed 2PC Transactions
From my good friend Franco Cravero. What your Windows2000 coders need to
know in order to be able to "Push" a MTS/DTC transaction to VMS. : -
Distributed Transactions with Microsoft
G.F.Cravero
Dataware Systems Ltd.
www.dataware-sys.com
Many applications use transactions to demarcate sections of processing that involve changing data that must be consistent as a whole. A transaction ensures that either all the data changed within its scope is saved, or none is. In other words, it is impossible for just some of the data modified in the transaction to be saved for later retrieval. Transactions have long been associated with databases, where transactional capabilities to handle stored data were first found. Commands for demarcating transactions can be found in all database languages, and Microsoft database interfaces (ActiveX Data Objects, OLE DB, ODBC and the older DAO) all support starting and terminating transactions against a single database.
DTC
--- To handle cases where more than one data source on several computers is involved in the processing, even when the source is not a database, Microsoft provides a service called the Distributed Transaction Coordinator (DTC). The DTC can act as either an XA-compliant resource manager or a transaction manager. When the DTC is acting as an XA-compliant resource manager, it allows Microsoft® SQL Server, Microsoft Message Queuing, and other OLE Transactions-compliant resource managers to participate in transactions controlled by X/Open DTP XA-compliant transaction processing monitors such as Encina, TopEnd, and Tuxedo. When the DTC is acting as an XA-compliant transaction manager, it allows Oracle, IBM DB/2, Sybase, Informix, and other XA-compliant resource managers to participate in transactions controlled by the DTC. COM --- Microsoft also provides a Compound Object Model (COM) for specifying binary-compatible software components that can interact and be used by multiple applications. This object model has recently been augmented with the transactional capabilities of what was known as the Microsoft Transaction Server and with other facilities such as those provided by Microsoft Message Queue to give the COM+ middle tier services. A COM object that is registered with the Component Services Explorer (a snap-in of the Microsoft Management Console tool ) becomes a managed service that can use amongst others declarative distributed transactional constraints. Therefore, DTC transactions can be started and terminated automatically by COM+ rather than having to be handled directly by the component's code. Code Samples ------------ Microsoft Visual C++ component of the Visual Studio suite allows COM components to be created easily via a wizard interface, generating a lot of ATL based code for the project. Assuming that such an object has been created, and that a new interface method has been defined, the following code snippets can be used within that method to manipulate distributed transactions. First of all, the CoGetObjectContext function can be used to check whether an object is being run within COM+, and hence whether transactions are handled declaratively or whether the DTC needs to be contacted directly. The following code shows how to perform this check: #include <ComSvcs.h> . . . HRESULT hr; IObjectContextInfo *pObjectContextInfo; hr = CoGetObjectContext (IID_IObjectContextInfo,(voidReceived on Thu Nov 25 2004 - 12:24:20 CST
**)&pObjectContextInfo);
if (SUCCEEDED(hr)) { // object being run within COM+, get transaction if any } else { // object not within COM+, start a transaction } The HRESULT type is declared in winnt.h, and the SUCCEEDED() macro is declared in winerror.h, which also contains a description of most error codes. For the sake of brevity, checks for failure against the codes returned by any of the function calls in the following code are omitted. To get a handle to the current transaction when run within COM+ the following code can be used: IUnknown *pTransUnknown; ITransaction *pTransaction hr = pObjectContextInfo->GetTransaction (&pTransUnknown); hr = pTransUnknown->QueryInterface (IID_ITransaction,(void
**)&pTransaction);
On the other hand, to start a new distributed transaction explicitly the code is: #include <XoleHlp.h> // define DTCGetTransactionManager (requires xolehlp.lib) . . . ITransactionDispenser *pTransactionDispenser; ITransaction *pTransaction hr = DtcGetTransactionManager( NULL, // pszHost NULL, // pszTmName IID_ITransactionDispenser, // ID of the interface 0, // Reserved: must be null 0, // Reserved: must be null 0, // Reserved: must be null (void **)&pTransactionDispenser // the interface ); hr = g_pTransactionDispenser->BeginTransaction ( 0, // Must be null ISOLATIONLEVEL_ISOLATED, // Isolation level ISOFLAG_RETAIN_DONTCARE, // Isolation flags 0, // Transaction options (void **)&pTransaction); // The transaction object Once a handle to the transaction has been obtained, a remote transaction manager can be contacted to enlist any remote services in the transaction. Microsoft provides support for non-DTC transaction managers that adhere to the Transaction Internet Protocol (TIP), as follows: ITipTransaction *tpTipTransaction; Char *remoteTxUrl; hr = pTransaction->QueryInterface (IID_ITipTransaction,(void
**)&pTipTransaction);
hr = tpTipTransaction->Push("tip://remotehost.co.uk/",&remoteTxUrl); Local work and remote work can then be carried out within the scope of the transaction provided that all the data sources involved support the transaction protocol and have a resource manager that is enlisted with each machine's transaction manager. In this case the application would send the remoteTxUrl over to the remote application for enlisting with its own (remote) transaction manager. Note that there is also a Pull method for enlisting remote transaction managers and resources in a transaction, not covered by this document. Note that when using ADO to perform work against a local database, only COM+ transactions can be joined as ADO automatically checks for the context and enlists the database with the transaction manager (the DTC in this case). Transactions that are started explicitly through the DTC cannot be joined as the underlying OLE DB interface for doing so is not surfaced by ADO. Once all the work is complete the transaction can be terminated by either committing or rolling back (undoing) the changes. The following code can be used to commit a transaction explicitly: hr = pTransaction->Commit (FALSE, XACTTC_ASYNC, 0); For transactions under COM+ control the composite object 'votes' for the transaction outcome as follows: IObjectContext *pObjectContext; hr = CoGetObjectContext (IID_IObjectContext,(void **)&pObjectContext); hr = pObjectContext->SetComplete(); The COM+ services will then commit or rollback the transaction according to how all the objects involved in the transaction have voted (a COM+ transaction can be declared to span multiple compound objects).