Building Distributed
Applications
Using the Progress AppServer
Implementing Automatic Transactions
To implement an automatic transaction, you provide a specially-coded remote procedure (transaction initiating procedure) that initializes a transaction object in the Application Server process where it executes. This transaction object is a permanent object in the session context that provides methods and attributes on a transaction object handle that allow the AppServer session to commit, rollback, or set and check the status of an automatic transaction. Because an automatic transaction terminates when the context of the transaction initiating procedure is deleted, you must execute the transaction initiating procedure persistently to make practical use of the transaction that it initiates.
Initializing the Automatic Transaction Object
To initialize the transaction object, you must create a transaction initiating procedure by specifying the TRANSACTION-MODE statement as the first executable statement in the procedure file:
When the client calls this transaction initiating procedure as a remote persistent procedure, an automatic transaction starts in the context of the AppServer session and can remain open after the remote procedure call returns to the client. The context for this open automatic transaction is the entire AppServer session, not (as you might think) the context internal to the transaction initiating procedure instantiated in the AppServer session. Thus, any remote procedure (persistent or non-persistent) that is subsequently executed participates in this open automatic transaction.
Controlling the Transaction
You can access the transaction object handle for the initialized transaction object using the TRANSACTION attribute on the procedure of any procedure executing in the AppServer session by using the THIS-PROCEDURE system handle:
You can then access the transaction object methods and attributes to control the transaction, as described in Table 4–2.
Terminating Automatic Transactions
An automatic transaction remains active as long as the context of the transaction initiating procedure remains active and you do not otherwise terminate the transaction using a transaction handle method. Thus, you can terminate an automatic transaction using two techniques:
- Explicit termination—You can explicitly terminate an automatic transaction on the AppServer with a reference to the SET-COMMIT( ) method or the SET-ROLLBACK( ) method:
As long as an automatic transaction is open, you can execute any internal procedure of the transaction initiating procedure from any other procedure running in the AppServer session. However, if no transaction is open, any such attempt to call these internal procedures from within the Application Server process context returns an error. Without an open transaction, only a client application can call a remote internal procedure of the transaction initiating procedure (see the "Restarting Automatic Transactions" section).
NOTE: You can determine whether an automatic transaction is open in an AppServer session by either checking for an error after executing an internal procedure of the transaction initiating procedure or by checking the value of the TRANS-INIT-PROCEDURE attribute.- Implicit termination—You can also terminate the automatic transaction from either the client or the AppServer session by deleting the proxy persistent procedure handle (on a 4GL client) or remote persistent procedure handle (on the AppServer) of the transaction initiating procedure. If you delete the transaction initiating procedure, the transaction commits or rolls back depending on the value of the transaction handle DEFAULT-COMMIT attribute.
Restarting Automatic Transactions
After an automatic transaction terminates, how an automatic transaction can restart depends on how it terminates. If the transaction terminates by deleting the transaction initiating procedure, only a client application can restart an automatic transaction by again remotely instantiating a transaction initiating procedure.
If a transaction initiating procedure is still active in the AppServer session, you can support the restarting of an automatic transaction using one of the following techniques, depending on how you code the transaction initiating procedure:
CAUTION: In general, try to keep automatic transactions on an AppServer as short as possible. The multi-request feature of automatic transactions tend to encourage long transactions, and long transactions can make large or important segments of a database inaccessible to other Progress sessions for an indefinite period. This can create database deadlocks and traffic jams that can seriously retard the performance of multiple sessions. For more information on techniques to shorten automatic transactions, see the information on transaction management considerations in Design and Implementation Considerations."
- Automatic (chained) restarting—If you specify the CHAINED option for the TRANSACTION-MODE AUTOMATIC statement, a new automatic transaction starts immediately after the previous automatic transaction commits or rolls back. Thus, with the CHAINED option an automatic transaction is always open in the AppServer session until the transaction initiating procedure, itself, is made inactive (is deleted).
- Manual restarting—If you do not specify the CHAINED option for the TRANSACTION-MODE AUTOMATIC statement, the client application can cause another automatic transaction to restart by calling any internal procedure of the active transaction initiating procedure. Thus, a remote call to an empty internal procedure can start a new automatic transaction.
Automatic Transaction Example
By including appropriate calls to internal procedures of the transaction initiating procedure in your remote procedures, you can encapsulate the management of a multi-request automatic transaction in a manner completely hidden from the client. However, the following example is relatively simple in that the client calls all of the internal procedures of the transaction initiating procedure directly, thus more openly exposing the transaction mechanism to the client.
The following two procedures include a transaction initiating procedure and a 4GL client procedure that accesses it.
The transaction initiating procedure (
a-txtest.p
) implements an unchained automatic transaction. This procedure provides three internal procedures that allow the client to explicitly start (startme), commit (stopme), and roll back (abortme) transactions.
The client procedure (
a-txclnt.p
) establishes the initial transaction object by instantiatinga-txtest.p
on the AppServer. After calling two database update procedures, the client commits the transaction with a call to stopme. It then begins a new transaction by calling startme, and after calling the same two database update procedures, rolls back the transaction by calling abortme.As noted in the comments
a-txtest.p
establishes an unchained transaction object. If the procedure instead establishes a chained transaction object, each time the current transaction terminates (stopme, abortme), the Application Server process automatically starts a new transaction with no need for the client to call a procedure (startme) to initiate it.
a-txclnt.p1DEFINE VARIABLE ph AS HANDLE. /*create a transaction initiating procedure and start the transaction*/
RUN a-txtest.p ON SERVER h TRANSACTION DISTINCT PERSISTENT SET ph.RUN custupdate.p ON SERVER h TRANSACTION DISTINCT. RUN orderupdate.p ON SERVER h TRANSACTION DISTINCT.
RUN stopme IN ph./*causes the transaction to commit including both custupdate and orderupdate*/ /*start another transaction by running an internal proc of a-txtest.p*/
RUN startme IN ph./*starts a new transaction -- this is unnecessary if the TRANSACTION-MODE statement in a-txtest.p specifies the CHAINED option*/ RUN custupdate.p ON SERVER h TRANSACTION DISTINCT. RUN orderupdate.p ON SERVER h TRANSACTION DISTINCT.
RUN abortme IN ph./*causes the transaction to roll back including both custupdate and orderupdate*/ DELETE PROCEDURE ph.
- The RUN statements in this example use the 4GL syntax for executing remote procedures of various types. For more information, see Programming the Client Application."
Note that while these examples show a close correlation between transaction directives and remote procedure requests, there is no requirement that this be so. You can completely hide any sense that the client is ultimately initiating and managing a transaction by hiding all calls to the internal procedures of the transaction initiating procedure within the logic of your application API. For example, you can encapsulate the remote procedure calls in
a-txclnt.p
in higher-level procedures, such asstart-updates.p
,rerun-updates.p
, andend-updates.p
.
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |