informix的XA编程
谁做过informix的XA编程 /****************************************************************************Licensed Materials - Property of IBM
*
*
*"Restricted Materials of IBM"
*
*
*
*IBM Informix Client SDK
*
*
*(C) Copyright IBM Corporation 1997, 2004 All rights reserved.
*
*
*
*
*
*Title: OnePhaseCommitRollback.c
*
*Description: Make X/Open XA calls to perform one-phase commit or
* one-phase rollback
*
*
***************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifndef NO_WIN32
#include <io.h>
#include <windows.h>
#include <conio.h>
#endif
#include "xa.h"
#include "infxcli.h"
#define MAXPROCS 500
#define MAX_ERR_MSG 255
#define ERRMSG_LEN200
int error_flag = 0;
struct xa_switch_t *OdbcXaSwitch;
#define xa_open(info, rmid, flags) \
((*OdbcXaSwitch->xa_open_entry)(info,rmid,flags))
#define xa_close(info, rmid, flags) \
((*OdbcXaSwitch->xa_close_entry)(info,rmid,flags))
#define xa_start(gtrid,rmid, flags) \
((*OdbcXaSwitch->xa_start_entry)(gtrid,rmid,flags))
#define xa_end(gtrid,rmid, flags) \
((*OdbcXaSwitch->xa_end_entry)(gtrid,rmid,flags))
#define xa_rollback(gtrid,rmid, flags) \
((*OdbcXaSwitch->xa_rollback_entry)(gtrid,rmid,flags))
#define xa_prepare(gtrid, rmid, flags) \
((*OdbcXaSwitch->xa_prepare_entry)(gtrid,rmid,flags))
#define xa_commit(gtrid, rmid, flags) \
((*OdbcXaSwitch->xa_commit_entry)(gtrid,rmid,flags))
#define xa_recover(gtrid,count,rmid, flags) \
((*OdbcXaSwitch->xa_recover_entry)(gtrid,count,rmid,flags))
#define xa_forget(gtrid,rmid, flags) \
((*OdbcXaSwitch->xa_forget_entry)(gtrid,rmid,flags))
#define xa_complete(handle, retval, rmid, flags) \
((*OdbcXaSwitch->xa_complete_entry)(handle,retval,rmid,flags))
int XAOpen(char *xa_info, int rmid, long flags)
{
int RCopen;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XAOpen: Calling xa_open ...");
if ((RCopen = xa_open(xa_info, rmid, flags)) != XA_OK)
{
printf("\n\tXAOpen: xa_open() returned %d\n", RCopen);
}
else
{
printf("Success %d.\n", RCopen);
}
return(RCopen);
}
int XAClose(char *xa_info, int rmid, long flags)
{
int RCclose;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XAClose: Calling xa_close ...");
if ((RCclose= xa_close(xa_info, rmid, flags)) != XA_OK)
{
printf("\n\tXAClose: xa_close() returned %d\n", RCclose);
}
else
{
printf("Success %d.\n", RCclose);
}
return(RCclose);
}
int XAStart(XID *var_xid, int rmid, long flags)
{
int RCstart;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XAStart: Calling xa_start ...");
if ((RCstart = xa_start(var_xid, rmid, flags)) != XA_OK)
{
printf("\n\tXAStart: xa_start() returned %d\n", RCstart);
}
else
{
printf("Success %d.\n", RCstart);
}
return(RCstart);
}
int XAEnd(XID *var_xid, int rmid, long flags)
{
int RCend;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XAEnd: Calling xa_end ...");
if ((RCend = xa_end(var_xid, rmid, flags)) != XA_OK)
{
printf("\n\tXAEnd: xa_end() returned %d\n",RCend);
}
else
{
printf("Success %d.\n", RCend);
}
return(RCend);
}
int XAPrepare(XID *var_xid, int rmid, long flags)
{
int RCPrepare;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XAPrepare: Calling xa_prepare ...");
if ((RCPrepare = xa_prepare(var_xid, rmid, flags)) != XA_OK)
{
printf("\n\tXAPrepare: xa_prepare() returned %d\n",RCPrepare);
}
else
{
printf("Success %d.\n", RCPrepare);
}
return(RCPrepare);
}
XACommit(XID *var_xid, int rmid, long flags)
{
int RCCommit;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XACommit: Calling xa_commit...");
if ((RCCommit = xa_commit(var_xid, rmid, flags)) != XA_OK)
{
printf("\n\tXACommit: xa_commit() returned %d\n", RCCommit);
}
else
{
printf("Success %d.\n", RCCommit);
}
return(RCCommit);
}
XARollback(XID *var_xid, int rmid, long flags)
{
int RCRollback;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XARollback: Calling xa_rollback...");
if ((RCRollback = xa_rollback(var_xid, rmid, flags)) != XA_OK)
{
printf("\n\tXARollback: xa_rollback() returned %d\n", RCRollback);
}
else
{
printf("Success %d.\n", RCRollback);
}
return(RCRollback);
}
XARecover(XID *var_xid, long count, int rmid, long flags)
{
int RCRecover;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XARecover: Calling xa_recover...");
if ((RCRecover = xa_recover(var_xid, count, rmid, flags)) != XA_OK)
{
printf("\n\tXARecover: xa_recover() returned %d\n", RCRecover);
}
else
{
printf("Success %d.\n", RCRecover);
}
return(RCRecover);
}
XAForget(XID *var_xid, int rmid, long flags)
{
int RCForget;
OdbcXaSwitch = _fninfx_xa_switch();
printf("XAForget: Calling xa_forget...");
if ((RCForget = xa_forget(var_xid, rmid, flags)) != XA_OK)
{
printf("\n\tXAForget: xa_forget() returned %d\n", RCForget);
}
else
{
printf("Success %d.\n", RCForget);
}
return(RCForget);
}
SQLINTEGER checkError (SQLRETURN rc,
SQLSMALLINT handleType,
SQLHANDLE handle,
SQLCHAR* errmsg)
{
SQLRETURN retcode = SQL_SUCCESS;
SQLSMALLINT errNum = 1;
SQLCHAR sqlState;
SQLINTEGER nativeError;
SQLCHAR errMsg;
SQLSMALLINT textLengthPtr;
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
{
while (retcode != SQL_NO_DATA)
{
retcode = SQLGetDiagRec (handleType, handle, errNum, sqlState, &nativeError, errMsg, ERRMSG_LEN, &textLengthPtr);
if (retcode == SQL_INVALID_HANDLE)
{
fprintf (stderr, "checkError function was called with an invalid handle!!\n");
return 1;
}
if ((retcode == SQL_SUCCESS) || (retcode == SQL_SUCCESS_WITH_INFO))
fprintf (stderr, "ERROR: %d:%s : %s \n", nativeError, sqlState, errMsg);
errNum++;
}
fprintf (stderr, "%s\n", errmsg);
return 1; /* all errors on this handle have been reported */
}
else
return 0; /* no errors to report */
}
main(int argc, char *argv[])
{
SQLCHAR defDsn[] = "odbc_demo";
char applTokenStr[] = "123";
char openInfo;
SQLCHAR dsn; /*name of the DSN used for connecting to the database*/
XID var_xid1, var_xid2;
RETCODE rc;
HANDLE hdbc, hstmt;
HENV henv;
int rmid =0;
int applToken;
/* If(dsn is not explicitly passed in as arg) */
if (argc != 2)
{
/* Use default dsn - odbc_demo */
fprintf (stdout, "\nUsing default DSN : %s\n", defDsn);
strcpy ((char *)dsn, (char *)defDsn);
}
else
{
/* Use specified dsn */
strcpy ((char *)dsn, (char *)argv);
fprintf (stdout, "\nUsing specified DSN : %s\n", dsn);
}
applToken = atoi(applTokenStr);
strcpy(openInfo, applTokenStr);
strcat(openInfo, (char *)"|");
strcat(openInfo, (char *)dsn);
fprintf (stdout, "\nUsing specified openInfo : %s\n", openInfo);
var_xid1.formatID = 100;
var_xid1.gtrid_length = 3;
var_xid1.bqual_length = 3;
var_xid1.data = 'A';
var_xid1.data = 'B';
var_xid1.data = 'A';
var_xid1.data = 'B';
var_xid1.data = 'A';
var_xid1.data = 'B';
var_xid2.formatID = 102;
var_xid2.gtrid_length = 3;
var_xid2.bqual_length = 3;
var_xid2.data = 'C';
var_xid2.data = 'D';
var_xid2.data = 'C';
var_xid2.data = 'D';
var_xid2.data = 'C';
var_xid2.data = 'D';
if ((rc = XAOpen(openInfo, rmid, TMNOFLAGS)) == XA_OK)
{
printf("\nXAOpen done ...");
printf("\nRmid set: [%i]\n",rmid);
}
else
{
printf("\n XAOpen Failed ... Aborting ...");
exit(1);
}
rc = IFMX_SQLGetXaHenv(applToken, &henv);
if (rc)
{
printf("\nIFMX_SQLGetXaHenv Failed ... Aborting ...");
exit(1);
}
rc = IFMX_SQLGetXaHdbc(applToken, &hdbc);
if (rc)
{
printf("\nIFMX_SQLGetXaHdbc Failed ... Aborting ...");
exit(1);
}
rc = XAStart(&var_xid1, rmid, TMNOFLAGS);
if (rc)
{
printf("\nXAStart Failed ... Aborting ...");
exit(1);
}
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, (SQLCHAR *) "SQLAllocHandle failed\nExiting!!\n"))
return (1);
printf("\n Inserting Values ...");
rc = SQLExecDirect(hstmt, (SQLCHAR *)"INSERT INTO xa_tab1 VALUES(1)", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "SQLExecDirect failed\nExiting!!\n"))
return (1);
printf ("\n Calling XAEnd on first transaction ...");
rc = XAEnd(&var_xid1, rmid, TMSUCCESS);
if (rc)
{
printf("\nXAEnd Failed ... Aborting ...Error Code: %d", rc);
exit(1);
}
rc = XACommit(&var_xid1, rmid, TMONEPHASE);
if (rc)
{
printf("\nXACommit Failed ... Aborting ...Error Code: %d", rc);
exit(1);
}
printf("\nCalling XAStart on second transaction...");
rc = XAStart(&var_xid2, rmid, TMNOFLAGS);
if (rc)
{
printf("\nXAStart Failed ... Aborting ...Error Code: %d", rc);
exit(1);
}
rc = SQLExecDirect(hstmt, (SQLCHAR *)"INSERT INTO xa_tab1 VALUES(2)", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "SQLExecDirect failed\nExiting!!\n"))
return (1);
rc = XAEnd(&var_xid2, rmid, TMSUCCESS);
if (rc)
{
printf("\nXAEnd Failed ... Aborting ...Error Code: %d", rc);
exit(1);
}
rc = XARollback(&var_xid2, rmid, TMNOFLAGS);
if (rc)
{
printf("\nXARollback Failed ... Aborting ...Error Code: %d", rc);
exit(1);
}
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "SQLFreeStmt failed\nExiting!!\n"))
return (1);
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, (SQLCHAR *) "SQLFreeHandle failed\nExiting!!\n"))
return (1);
rc = XAClose(openInfo, rmid, TMNOFLAGS);
if (rc)
{
printf("\nXARollback Failed ... Aborting ...Error Code: %d", rc);
exit(1);
}
exit(0);
} 太感谢你了。
直接esql就行吗?
页:
[1]