TRANRDY
Executes the first phase of a two-phase transaction commit.
Short Name
TRANRDY()
Type
Low-Level function
Declaration
COUNT TRANRDY()
Description
Two-Phase transaction support allows, for example, a transaction to span multiple servers. This is useful for updating information from a master database to remote databases in an all-or-nothing approach.
To start a transaction that supports a two-phase commit, you would include the ctTWOFASE attribute in the transaction mode passed to the Begin() function. Call the TRANRDY() function to execute the first commit phase, and finally Commit() to execute the second commit phase.
Note: You may need additional caution with regard to locking and unlocking of records as your transactions become more complex in a multi-server environment to avoid performance problems.
Caution: Two-Phase transactions can become extremely difficult to debug should there be communications problems between servers at any time during the second commit phase. This can result in out of sync data between the servers as one server may have committed while another server failed. It is always appropriate to check the return codes of the individual Commit() functions to ensure a complete successful transaction commit across multiple servers.
Return
Value |
Symbolic Constant |
Explanation |
---|---|---|
0 |
CTDBRET_OK |
Successful operation. |
71 |
TNON_ERR |
No active transaction. |
94 |
PNDG_ERR |
Pending error: cannot save or commit tran. |
See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.
Example
(Note that this example could also use individual threads of operation for the different c-tree Server connections, avoiding the c-tree instance calls.)
COUNT rc1,rc2;
FILNO filno1,filno2;
COUNT rcc1,rcc2;
TEXT databuf1[128],databuf2[128];
/* Create the connections and c-tree instances */
...
if (!RegisterCtree("server_1")) {
SwitchCtree("server_1");
InitISAMXtd(10, 10, 64, 10, 0, "ADMIN", "ADMIN", "FAIRCOMS1");
filno1 = OPNRFIL(0, "mydata.dat", ctSHARED);
FirstRecord(filno1, databuf1);
memcpy (databuf1, "new data", 8);
/* Prepare transaction on c-tree server 1 */
Begin(ctTRNLOG | ctTWOFASE | ctENABLE);
ReWriteRecord(filno1, databuf1);
rc1 = TRANRDY();
}
if (!RegisterCtree("server_2")) {
SwitchCtree("server_2");
InitISAMXtd(10, 10, 64, 10, 0, "ADMIN", "ADMIN", "FAIRCOMS2");
filno2 = OPNRFIL(0, "mydata.dat", ctSHARED);
FirstRecord(filno2, databuf2);
memcpy (databuf2, "new data", 8);
/* Prepare transaction on c-tree server 2 */
Begin(ctTRNLOG | ctTWOFASE | ctENABLE);
ReWriteRecord(filno2, databuf2);
rc2 = TRANRDY();
}
/* Commit the transactions */
if (!rc1 && !rc2) {
SwitchCtree("server_1");
rcc1 = Commit(ctFREE);
SwitchCtree("server_2");
rcc2 = Commit(ctFREE);
if (!rcc1 && !rcc2) {
printf("Transaction successfully committed across both servers.\n");
} else {
printf("One or more units of the second commit phase of the transaction failed: rcc1=%d rcc2=%d\n", rcc1, rcc2);
}
} else {
printf("One or more of the transactions failed to be prepared: rc1=%d rc2=%d\n", rc1, rc2);
printf("Pending transactions will be aborted.\n");
SwitchCtree("server_1");
Abort();
SwitchCtree("server_2");
Abort();
}
/* Done */
SwitchCtree("server_1");
CloseISAM();
SwitchCtree("server_2");
CloseISAM();
See also
Abort(), AbortXtd(), Begin(), ClearSavePoint(), Commit(), RestoreSavePoint(), SetSavePoint()