TWOPHASE.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:6k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /* Demo of Two-Phase Commit Service
  2. **
  3. ** This example uses the two-phase commit service
  4. ** to perform a simultaneous update on two servers.
  5. ** In this example, one of the servers participating
  6. ** in the distributed transaction also functions as
  7. ** the commit service.
  8. **
  9. ** In this particular example, the same update is
  10. ** performed on both servers. You can, however, use
  11. ** the commit server to perform completely different
  12. ** updates on each server.
  13. **
  14. */
  15. #if defined(DBNTWIN32)
  16. #include <windows.h>
  17. #endif
  18. #include <stdio.h>
  19. #include <sqlfront.h>
  20. #include <sqldb.h>
  21. char cmdbuf[256];
  22. char xact_string[128];
  23. /* Forward declarations of the error handler and message handler. 
  24. */
  25. int err_handler(DBPROCESS*, int, int, int, char*, char*);
  26. int msg_handler(DBPROCESS*, DBINT, int, int, char*);
  27. void abortall (DBPROCESS * dbproc_server1, DBPROCESS * dbproc_server2, DBPROCESS * dbproc_commit, DBINT commid);
  28. void main(argv,argc)
  29. int argc;
  30. char *argv[];
  31. {
  32. DBPROCESS *dbproc_server1;
  33. DBPROCESS *dbproc_server2;
  34. DBPROCESS *dbproc_commit;
  35. LOGINREC *login;
  36. DBINT commid;
  37. RETCODE ret_server1;
  38. RETCODE ret_server2;
  39. // set error/msg handlers for this program
  40. dbmsghandle((DBMSGHANDLE_PROC)msg_handler);
  41. dberrhandle((DBERRHANDLE_PROC)err_handler);
  42. /* Open connections with the servers and the commit service. */
  43. printf("Demo of Two Phase Commitn");
  44. login = dblogin();
  45. DBSETLUSER(login, "user");
  46. DBSETLPWD(login, "my_passwd");
  47. DBSETLAPP(login, "example");
  48. DBSETLVERSION(login, DBVER60);
  49.     
  50. dbproc_server1 = dbopen (login, "my_server1");
  51. dbproc_server2 = dbopen (login, "my_server2");
  52. dbproc_commit = open_commit (login, "my_commitsrv");
  53. if (dbproc_server1 == NULL ||
  54. dbproc_server2 == NULL ||
  55. dbproc_commit == NULL)
  56. {
  57. printf (" Connections failed!n");
  58. exit (ERREXIT);
  59. }
  60. /* Use the "pubs" database. */
  61. dbuse(dbproc_server1, "pubs");
  62. dbuse(dbproc_server2, "pubs");
  63. /* Start the distributed transaction on the commit service. */
  64. commid = start_xact(dbproc_commit, "demo", "test", 2);
  65. /* Build the transaction name. */
  66. build_xact_string ("test", "my_commitsrv", commid, xact_string);
  67. /* Build the first command buffer. */
  68. sprintf(cmdbuf, "BEGIN TRANSACTION %s", xact_string);
  69. /* Begin the transactions on the different servers. */
  70. dbcmd(dbproc_server1, cmdbuf);
  71. dbsqlexec(dbproc_server1);
  72. dbcmd(dbproc_server2, cmdbuf);
  73. dbsqlexec(dbproc_server2);
  74. dbcancel(dbproc_server1);
  75. dbcancel(dbproc_server2);
  76. /* Do various updates. */
  77. sprintf(cmdbuf, " update titles set price = $1.50 where");
  78. strcat(cmdbuf, " title_id = 'BU1032'");
  79. dbcmd(dbproc_server1, cmdbuf);
  80. ret_server1 = dbsqlexec(dbproc_server1);
  81. dbcmd(dbproc_server2, cmdbuf);
  82. ret_server2 =dbsqlexec(dbproc_server2);
  83. if (ret_server1 == FAIL || ret_server2 == FAIL)
  84. {
  85. /* Some part of the transaction failed. */
  86. printf(" Transaction aborted -- dbsqlexec failedn");
  87. abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
  88. }
  89. dbcancel(dbproc_server1);
  90. dbcancel(dbproc_server2);
  91. /* Find out if all servers can commit the transaction. */
  92. sprintf(cmdbuf, "PREPARE TRANSACTION");
  93. dbcmd(dbproc_server1, cmdbuf);
  94. dbcmd(dbproc_server2, cmdbuf);
  95. ret_server1 = dbsqlexec(dbproc_server1);
  96. ret_server2 = dbsqlexec(dbproc_server2);
  97. if (ret_server1 == FAIL || ret_server2 == FAIL)
  98. {
  99. /* One or both of the servers failed to prepare. */
  100. printf(" Transaction aborted -- PREPARE failedn");
  101. abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
  102. }
  103. dbcancel(dbproc_server1);
  104. dbcancel(dbproc_server2);
  105. /* Commit the transaction. */
  106. if (commit_xact(dbproc_commit, commid) == FAIL)
  107. {
  108. /* The commit server failed to record the commit. */
  109. printf( " Transaction aborted -- commit_xact failedn");
  110. abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
  111. exit(ERREXIT);
  112. }
  113. /* The transaction has successfully committed. Inform the servers. 
  114. */
  115. sprintf(cmdbuf, "COMMIT TRANSACTION");
  116. dbcmd(dbproc_server1, cmdbuf);
  117. if (dbsqlexec(dbproc_server1) != FAIL)
  118. remove_xact(dbproc_commit, commid, 1);
  119. dbcmd(dbproc_server2, cmdbuf);
  120. if (dbsqlexec(dbproc_server2) != FAIL)
  121. remove_xact(dbproc_commit, commid, 1);
  122. /* Close the connection to the commit server. */
  123. close_commit(dbproc_commit);
  124. printf( "We made it!n");
  125. dbexit();
  126. exit(STDEXIT);
  127. }
  128. /* Function to abort the distributed transaction. */
  129. void abortall( dbproc_server1, dbproc_server2, dbproc_commit, commid )
  130. DBPROCESS *dbproc_server1;
  131. DBPROCESS *dbproc_server2;
  132. DBPROCESS *dbproc_commit;
  133. DBINT commid;
  134. {
  135. /* Some part of the transaction failed. */
  136. /* Inform the commit server of the failure. */
  137. abort_xact(dbproc_commit, commid);
  138. /* Roll back the transactions on the different servers. */
  139. sprintf(cmdbuf, "ROLLBACK TRANSACTION");
  140. dbcmd(dbproc_server1, cmdbuf);
  141. if (dbsqlexec(dbproc_server1) != FAIL)
  142. remove_xact(dbproc_commit, commid, 1);
  143. dbcmd(dbproc_server2, cmdbuf);
  144. if (dbsqlexec(dbproc_server2) != FAIL)
  145. remove_xact(dbproc_commit, commid, 1);
  146. dbexit();
  147. exit(ERREXIT);
  148. }
  149. /* Message and error handling functions. */
  150. int msg_handler(dbproc,msgno,msgstate, severity, msgtext)
  151. DBPROCESS *dbproc;
  152. DBINT msgno;
  153. int msgstate;
  154. int severity;
  155. char *msgtext;
  156. {
  157. /* Msg 5701 is just a USE DATABASE message, so skip it. */
  158. if (msgno == 5701)
  159. return (0);
  160. /* Print any severity 0 message as is, without extra stuff. */
  161. if (severity == 0)
  162. {
  163. printf ("%sn",msgtext);
  164. return (0);
  165. }
  166. printf("SQL Server message %ld, severity %d:nt%sn",
  167. msgno, severity, msgtext);
  168. if (severity >>= 16)
  169. {
  170. printf("Program Terminated! Fatal SQL Server error.n");
  171. exit(ERREXIT);
  172. }
  173. return (0);
  174. }
  175. int err_handler(dbproc, severity, dberr, oserr, dberrstr, oserrstr)
  176. DBPROCESS *dbproc;
  177. int severity;
  178. int dberr;
  179. int oserr;
  180. char *dberrstr;
  181. char *oserrstr;
  182. {
  183. if ((dbproc == NULL) || (DBDEAD(dbproc)))
  184. return (INT_EXIT);
  185. else
  186. {
  187. printf ("DB-LIBRARY error: nt%sn", dberrstr);
  188. if (oserr != DBNOERR)
  189. printf ("Operating system error:nt%sn", oserrstr);
  190. }
  191. return (INT_CANCEL);
  192. }