Geeks With Blogs
Pradeep Loganathan Distributed

Was playing around with MSDTC today and had a a big gotcha. If you get any issues with the distrubuted transaction check this. Go to Component services MMC and right click on My Computer --> Properties and then click on the MSDTC tab and then on Security configuration . Make sure that “Network DTC access ” is checked and so is “No authentication required”.

I have also posted some sample code for directly working on the MSDTC transactions.

#include <windows.h>

#include <stdio.h>

#include <oledb.h>

#include <oledberr.h>

#include <txdtc.h>

#include <xolehlp.h>

#include <sql.h>

#include <sqlext.h>

#include <Odbcss.h>

void main()

{

ITransactionDispenser *pTransactionDispenser;

ITransaction *pTransaction;

HRESULT hr = S_OK;

SQLHENV henv;

SQLHDBC hdbc1, hdbc2;

SQLHSTMT hstmt1, hstmt2;

SQLRETURN retcode;

SQLCHAR sqlstmt1[]="insert into TEST1 values('hello')";

SQLCHAR sqlstmt2[]="insert into TEST2 values('hello')";

SQLCHAR* theDiagState = new SQLCHAR[50];

SQLINTEGER theNativeState;

SQLCHAR* theMessageText = new SQLCHAR[255];

SQLSMALLINT iOutputNo;

hr = DtcGetTransactionManager(0, 0, IID_ITransactionDispenser, 0, 0, 0, (void**)&pTransactionDispenser);

if(FAILED(hr))

{

printf("Failed to get the transaction manager" );

}

 

SQLAllocEnv(&henv);

SQLAllocConnect(henv,&hdbc1);

SQLAllocConnect(henv,&hdbc2);

retcode = SQLConnect(hdbc1, (SQLCHAR*) "blrdevlabsvr12DSN", SQL_NTS,

(SQLCHAR*) "sa", SQL_NTS,

(SQLCHAR*) "", SQL_NTS);

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)

printf("Connected to 1........");

retcode = SQLConnect(hdbc2, (SQLCHAR*) "seconddsn", SQL_NTS,

(SQLCHAR*) "sa", SQL_NTS,

(SQLCHAR*) "", SQL_NTS);

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)

printf("Connected to 2........");

hr = pTransactionDispenser->BeginTransaction (NULL,ISOLATIONLEVEL_READCOMMITTED,ISOFLAG_RETAIN_DONTCARE, NULL, &pTransaction );

if (FAILED (hr))

{

printf("BeginTransaction failed: Error # %#x\n", hr);

exit(1); // Replace with specific error handling.

}

hr = SQLSetConnectAttr (hdbc1, SQL_COPT_SS_ENLIST_IN_DTC,(SQLPOINTER)pTransaction,SQL_IS_INTEGER);

if (hr != SQL_SUCCESS)

{

SQLGetDiagRec(SQL_HANDLE_DBC,hdbc1,1,(SQLCHAR*)theDiagState,&theNativeState,(SQLCHAR*)theMessageText,100,&iOutputNo);

printf( "Error :%s\n%d", theMessageText,iOutputNo);

}

hr = SQLSetConnectAttr (hdbc2, SQL_COPT_SS_ENLIST_IN_DTC,(SQLPOINTER)pTransaction,SQL_IS_INTEGER);

if (hr != SQL_SUCCESS)

{

SQLGetDiagRec(SQL_HANDLE_DBC,hdbc1,1,(SQLCHAR*)theDiagState,&theNativeState,(SQLCHAR*)theMessageText,100,&iOutputNo);

printf( "Error :%s\n", theMessageText);

}

 

retcode = SQLAllocStmt(hdbc1, &hstmt1);

retcode = SQLAllocStmt(hdbc2, &hstmt2);

retcode = SQLExecDirect(hstmt1,sqlstmt1, SQL_NTS);

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)

printf("Executed 1........");

retcode = SQLExecDirect(hstmt2,sqlstmt2, SQL_NTS);

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)

printf("Executed 2........");

 

SQLFreeStmt(hstmt1,SQL_DROP);

SQLFreeStmt(hstmt2,SQL_DROP);

hr = pTransaction->Commit(FALSE,XACTTC_SYNC_PHASEONE,0);

SQLDisconnect(hdbc1);

SQLFreeConnect(hdbc1);

SQLDisconnect(hdbc2);

SQLFreeConnect(hdbc2);

SQLFreeEnv(henv);

}

I will be explaining this in my next post. It is pretty late out here :-(

 

 

Posted on Tuesday, January 17, 2006 12:27 PM Transactions | Back to top

Copyright © Pradeep Loganathan | Powered by: GeeksWithBlogs.net