BEA Logo BEA Tuxedo Release 8.0

  BEA Home  |  Events  |  Solutions  |  Partners  |  Products  |  Services  |  Download  |  Developer Center  |  WebSUPPORT

 

   Tuxedo Documentation   |   Programming BEA Tuxedo ATMI Applications Using C   |   Local Topics   |   Previous Topic   |   Next Topic   |   Contents

 


Testing Whether a Transaction Has Started

When a process in transaction mode requests a service from another process, the latter process becomes part of the transaction, unless specifically instructed not to join it.

It is important to know whether or not a process is in transaction mode in order to avoid and interpret certain error conditions. For example, it is an error for a process already in transaction mode to call tpbegin(). When tpbegin() is called by such a process, it fails and sets tperrno(5) to TPEPROTO to indicate that it was invoked while the caller was already participating in a transaction. The transaction is not affected.

You can design a service subroutine so that it tests whether it is in transaction mode before invoking tpbegin(). You can test the transaction level by either of the following methods:

Use the following signature to call the tpgetlev() function:

int
tpgetlev() /* Get current transaction level */

The tpgetlev() function requires no arguments. It returns 0 if the caller is not in a transaction, and 1 if it is.

The following code sample is a variation of the OPEN_ACCT servicethat shows how to test for transaction level using the tpgetlev() function (line 12). If the process is not already in transaction mode, the application starts a transaction (line 14). If tpbegin() fails, a message is returned to the status line (line 16) and the rcode argument of tpreturn() is set to a code that can be retrieved in the global variable tpurcode(5) (lines 1 and 17).

Testing Transaction Level

001 #define BEGFAIL    3    /* tpurcode setting for return if tpbegin fails */

002 void
003 OPEN_ACCT(transb)

004 TPSVCINFO *transb;

005 {
... other declarations ...
006 FBFR *transf; /* fielded buffer of decoded message */
007 int dotran; /* checks whether service tpbegin/tpcommit/tpaborts */

008 /* set pointer to TPSVCINFO data buffer */

009 transf = (FBFR *)transb->data;

010 /* Test if transaction exists; initiate if no, check if yes */

011 dotran = 0;
012 if (tpgetlev() == 0) {
013 dotran = 1;
014 if (tpbegin(30, 0) == -1) {
015 Fchg(transf, STATLIN, 0,
016 "Attempt to tpbegin within service routine failed\n");
017 tpreturn(TPFAIL, BEGFAIL, transb->data, 0, 0);
018 }
019 }
. . .

If the AUTOTRAN parameter is set to Y, you do not need to call the tpbegin(), and tpcommit() or tpabort() transaction functions explicitly. As a result, you can avoid the overhead of testing for transaction level. In addition, you can set the TRANTIME parameter to specify the time-out interval: the amount of time that may elapse after a transaction for a service begins, and before it is rolled back if not completed.

For example, suppose you are revising the OPEN_ACCT service shown in the preceding code listing. Currently, OPEN_ACCT defines the transaction explicitly and then tests for its existence (see lines 7 and 10-19). To reduce the overhead introduced by these tasks, you can eliminate them from the code. Therefore, you need to require that whenever OPEN_ACCT is called, it is called in transaction mode. To specify this requirement, enable the AUTOTRAN and TRANTIME system parameters in the configuration file.

See Also

 

back to top previous page next page