⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twophase.c

📁 在SCO UNIX5.05
💻 C
字号:
/*
** Confidential property of Sybase, Inc.
** (c) Copyright Sybase, Inc. 1992 to ???
** All rights reserved.
*/

/*
** %M%:      %I%      %G%      %U%
**  
**  
**  
*/
#if USE_SCCSID
static char Sccsid[] = {"%Z% %M% %I% %G%"};
#endif /* USE_SCCSID */

/*	
**	twophase.c
**
**	Demo of Two-Phase Commit Service
**
**	This example uses the two-phase commit service
**	to perform a simultaneous update on two servers.
**	In this example, one of the servers participating 
**	in the distributed transaction also functions as 
**	the commit service.
**
**	In this particular example, the same update is 
**	performed on both servers. You can, however, use 
**	the commit server to perform completely different 
**	updates on each server.
**
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sybfront.h>
#include <sybdb.h>
#include "sybdbex.h"

char     cmdbuf[256];
char     xact_string[128];

/*  Forward declaration	 */
void abortall PROTOTYPE(( DBPROCESS*, DBPROCESS*, DBPROCESS*, int));

main()
{

	DBPROCESS     *dbproc_server1; 
	DBPROCESS     *dbproc_server2;
	DBPROCESS     *dbproc_commit;
	LOGINREC      *login;
	int           commid;

	RETCODE       ret_server1;
	RETCODE       ret_server2;

	printf("Demo of Two Phase Commit\n\n");
	fflush(stdout);

	/* Initialize DB-Library. */
	if (dbinit() == FAIL)
		exit(ERREXIT);

	dberrhandle(err_handler);
	dbmsghandle(msg_handler);

	/* Open connections with the servers and the commit service. */
	login = dblogin();
	DBSETLUSER(login, USER);
	DBSETLPWD(login, PASSWORD);
	DBSETLAPP(login, "twophase");

	dbproc_server1 = dbopen (login, "SERVICE");
	dbproc_server2 = dbopen (login, "PRACTICE");
	dbproc_commit = open_commit (login, "SERVICE");

	if (dbproc_server1 == NULL || 
	    dbproc_server2 == NULL || 
	    dbproc_commit  == NULL)
	{
		dbexit();
		printf (" Connections failed!\n");
		exit (ERREXIT);
	}

	/* Use the "pubs2" database. */
	sprintf(cmdbuf, "use pubs2");
	dbcmd(dbproc_server1, cmdbuf);
	dbsqlexec(dbproc_server1);
	dbcmd(dbproc_server2, cmdbuf);
	dbsqlexec(dbproc_server2);

	/* Start the distributed transaction on the commit service. */
	commid = start_xact(dbproc_commit, "demo", "test", 2);

	/* Build the transaction name. */
	build_xact_string ("test", "SERVICE", commid, xact_string);

	/* Build the first command buffer. */
	sprintf(cmdbuf, "BEGIN TRANSACTION %s", xact_string);

	/* Begin the transactions on the different servers. */
	dbcmd(dbproc_server1, cmdbuf);
	dbsqlexec(dbproc_server1);
	dbcmd(dbproc_server2, cmdbuf);
	dbsqlexec(dbproc_server2);

	/* Do various updates. */
	sprintf(cmdbuf, " update titles set price = $1.50 where");
	strcat(cmdbuf, " title_id = 'BU1032'");
	dbcmd(dbproc_server1, cmdbuf);
	ret_server1 = dbsqlexec(dbproc_server1);
	dbcmd(dbproc_server2, cmdbuf);
	ret_server2 =dbsqlexec(dbproc_server2);
	if (ret_server1 == FAIL || ret_server2 == FAIL)
	{
		/* Some part of the transaction failed. */
		printf(" Transaction aborted -- dbsqlexec failed\n");
		abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
	}

	/* Find out if all servers can commit the transaction. */
	sprintf(cmdbuf, "PREPARE TRANSACTION");
	dbcmd(dbproc_server1, cmdbuf);
	dbcmd(dbproc_server2, cmdbuf);
	ret_server1 = dbsqlexec(dbproc_server1);
	ret_server2 = dbsqlexec(dbproc_server2);
	if (ret_server1 == FAIL || ret_server2 == FAIL)
	{
		/* One or both of the servers failed to prepare. */
		printf(" Transaction aborted -- PREPARE failed\n");
		abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
	}

	/* Commit the transaction. */
	if (commit_xact(dbproc_commit, commid) == FAIL)
	{
		/* The commit server failed to record the commit. */
		printf( " Transaction aborted -- commit_xact failed\n");
		abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
	}

	/* The transaction has successfully committed.  Inform the servers. */
	sprintf(cmdbuf, "COMMIT TRANSACTION");
	dbcmd(dbproc_server1, cmdbuf);
	if (dbsqlexec(dbproc_server1) != FAIL)
		remove_xact(dbproc_commit, commid, 1);
	dbcmd(dbproc_server2, cmdbuf);
	if (dbsqlexec(dbproc_server2) != FAIL)
		remove_xact(dbproc_commit, commid, 1);

	/* Close the connection to the commit server. */
	close_commit(dbproc_commit);

	printf( "We made it!\n");
	dbexit();
	exit(STDEXIT);
}

/* Function to abort the distributed transaction. */

void abortall( dbproc_server1, dbproc_server2, dbproc_commit, commid )
DBPROCESS      *dbproc_server1; 
DBPROCESS      *dbproc_server2;
DBPROCESS      *dbproc_commit;
int            commid;
{
	/* Some part of the transaction failed. */

	/* Inform the commit server of the failure. */
	abort_xact(dbproc_commit, commid);

	/* Roll back the transactions on the different servers. */
	sprintf(cmdbuf, "ROLLBACK TRANSACTION");
	dbcmd(dbproc_server1, cmdbuf);
	if (dbsqlexec(dbproc_server1) != FAIL)
		remove_xact(dbproc_commit, commid, 1);
	dbcmd(dbproc_server2, cmdbuf);
	if (dbsqlexec(dbproc_server2) != FAIL)
		remove_xact(dbproc_commit, commid, 1);

	dbexit();
	exit(ERREXIT);
}

/* Message and error handling functions. */

int msg_handler(dbproc, msgno, msgstate, severity, msgtext, 
                servername, procname, line)

DBPROCESS       *dbproc;
DBINT           msgno;
int             msgstate;
int             severity;
char            *msgtext;
char            *servername;
char            *procname;
DBUSMALLINT     line;

{
	/*   Msg 5701 is just a USE DATABASE message, so skip it.  */
	if (msgno == 5701)
		return (0);

	/*  Print any severity 0 message as is, without extra stuff.  */
	if (severity == 0)
	{
		fprintf (ERR_CH, "%s\n",msgtext);
		return (0);
	}

	fprintf (ERR_CH, "Msg %ld, Level %d, State %d\n", 
	        msgno, severity, msgstate);

	if (strlen(servername) > 0)
		fprintf (ERR_CH, "Server '%s', ", servername);
	if (strlen(procname) > 0)
		fprintf (ERR_CH, "Procedure '%s', ", procname);
	if (line > 0)
		fprintf (ERR_CH, "Line %d", line);

	fprintf (ERR_CH, "\n\t%s\n", msgtext);

	if (severity >= 16)
	{
		dbexit();
		fprintf (ERR_CH, "Program Terminated! Fatal SQL Server error.\n");
		exit(ERREXIT);
	}

	return (0);   
}

int err_handler(dbproc, severity, dberr, oserr, dberrstr, oserrstr)
DBPROCESS    *dbproc;
int          severity;
int          dberr;
int          oserr;
char         *dberrstr;
char         *oserrstr;
{
    if ((dbproc == (DBPROCESS *)NULL) || (DBDEAD(dbproc)))
        return(INT_EXIT);
    else 
    {
        fprintf (ERR_CH, "DB-Library error:\n\t%s\n", dberrstr);

        if (oserr != DBNOERR)
            fprintf (ERR_CH, "Operating-system error:\n\t%s\n", oserrstr);

        return(INT_CANCEL);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -