2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
8 * This is the code for the two servers used in the first XA test. Server 1
9 * and Server 2 are both called by the client to insert data into table 1
10 * using XA transactions. Server 1 also can forward requests to Server 2.
12 #include <sys/types.h>
31 #include "htimestampxa.h"
32 #include "../utilities/bdb_xa_util.h"
35 * The two servers are largely identical, #ifdef the source code.
38 #define TXN_FUNC TestTxn1
39 #define TXN_STRING "TestTxn1"
42 #define TXN_FUNC TestTxn2
43 #define TXN_STRING "TestTxn2"
45 void TXN_FUNC(TPSVCINFO *);
47 #define HOME "../data"
51 int cnt_forward; /* Forwarded requests. */
52 int cnt_request; /* Total requests. */
54 char *progname; /* Server run-time name. */
57 * Called when each server is started. It creates and opens the
58 * two database handles.
61 tpsvrinit(int argc, char* argv[])
64 return (init_xa_server(NUMDB, progname, 0));
67 /* Called when the servers are shutdown. This closes the databases. */
71 close_xa_server(NUMDB, progname);
72 printf("%s: %d requests, %d requests forwarded to the other server\n",
73 progname, cnt_request, cnt_forward);
77 * This function is called by the client. Here Server 1 and Server 2 insert
78 * data into table 1 using XA transactions. Server 1 can also forward its
79 * request to Server 2.
82 TXN_FUNC(TPSVCINFO *msg)
95 * Test that servers can forward to other servers. Randomly forward
96 * half of server #1's requests to server #2.
103 (FBFR*)tpalloc("FML32", NULL, replyLen)) == NULL ||
104 tpcall("TestTxn2", msg->data,
105 0, (char**)&replyBuf, &replyLen, TPSIGRSTRT) == -1) {
106 fprintf(stderr, "%s: TUXEDO ERROR: %s (code %d)\n",
107 progname, tpstrerror(tperrno), tperrno);
108 tpfree((char*)replyBuf);
109 tpreturn(TPFAIL, 0L, 0, 0L, 0);
111 tpfree((char*)replyBuf);
112 tpreturn(TPSUCCESS, tpurcode, 0, 0L, 0);
117 /* Read the record. */
118 if (Fget((FBFR*)msg->data, SEQ_NO, 0, (char *)&rcrd.SeqNo, 0) == -1)
120 if (Fget((FBFR*)msg->data, TS_SEC, 0, (char *)&rcrd.Ts.Sec, 0) == -1)
123 (FBFR*)msg->data, TS_USEC, 0, (char *)&rcrd.Ts.Usec, 0) == -1) {
124 fml_err: fprintf(stderr, "%s: FML ERROR: %s (code %d)\n",
125 progname, Fstrerror(Ferror), Ferror);
129 seqNo = rcrd.SeqNo; /* Update the record. */
130 memset(&key, 0, sizeof(key));
132 key.size = sizeof(seqNo);
133 memset(&data, 0, sizeof(data));
135 data.size = sizeof(seqNo);
138 __db_prdbt(&key, 0, "put: key: %s\n", stdout,
140 __db_prdbt(&data, 0, "put: data: %s\n", stdout,
144 for (i = 0; i < NUMDB; i++) {
145 strcpy(rcrd.Msg, db_names[i]);
146 if ((ret = dbs[i]->put(dbs[i], NULL, &key,
148 if (ret == DB_LOCK_DEADLOCK)
150 fprintf(stderr, "%s: %s: %s->put: %s\n",
151 progname, TXN_STRING, db_names[i],
158 * Decide if the client is going to commit the global transaction or
159 * not, testing the return-value path back to the client; this is the
160 * path we'd use to resolve deadlock, for example. Commit 80% of the
161 * time. Returning 0 causes the client to commit, 1 to abort.
163 if (rand() % 10 > 7) {
165 printf("%s: %s: commit\n", progname, TXN_STRING);
166 tpreturn(TPSUCCESS, 0L, 0, 0L, 0);
169 printf("%s: %s: abort\n", progname, TXN_STRING);
170 tpreturn(TPSUCCESS, 1L, 0, 0L, 0);
174 err: tpreturn(TPFAIL, 1L, 0, 0L, 0);