Product Documentation

FairCom ISAM for C

Previous Topic

Next Topic

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

NO_ERROR

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()

TOCIndex