![]() |
![]() |
|
|
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
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|