Maintaining transaction consistency between client and AppServer
One disadvantage of using normal ABL transactions on the AppServer is that, because a normal ABL transaction completes and releases all locks before returning to the client, you may have to do extra work to ensure that the transaction completes as the client expects.
A typical scenario where this behavior might pose a problem is where the AppServer returns data derived from a database to a client application. The client then modifies the data and returns it to the AppServer with the intent that the changes to the data are to be applied to the database. Because database locks are not held across interactions with the AppServer, the AppServer cannot simply change the data in the database because the data might have already been changed by another user. Thus, transaction consistency in this situation cannot be easily maintained.
One approach to work around this problem, especially on a state-aware or state-reset AppServer is to have the AppServer keep a copy of the original data that is returned to the client application. On an AppServer running in state-reset operating mode, state-aware operating mode, or stateless operating mode over a bound connection, you can maintain a separate buffer or temp-table to hold a copy of the data. On a stateless AppServer over an unbound connection, you must use the SERVER-CONNECTION-CONTEXT attribute of the SESSION system handle or a context database to maintain a copy of the data. For more information, see the sections on managing stateless connection context in Programming the AppServer.
When it is time to apply the updated data, the AppServer agent handling the request determines whether the database was changed by another user by comparing the original data to the data in the database. The following figure describes this approach.
Figure 6. Transaction data flow
The numbers in the previous figure correspond to the following explanation of transaction data flow:
1. The client application runs a remote persistent procedure on the AppServer to request the data. The AppServer gets the data from the database and stores it in a temp-table (Orig).
2. As a result of the remote persistent procedure call, the AppServer returns a copy of the Orig temp-table to the client application (Client).
3. The client application makes application-specific changes to its copy (Client~) that include creating, deleting, and modifying records.
4. The client application sends its modified copy (Client~) to the AppServer by running an internal procedure of the persistent procedure instantiated in Step 1. The AppServer stores its copy of the table in Client-Out.
5. Within a single transaction, the AppServer compares the records that are in the Orig temp-table to the data in the database. If there are any differences, the AppServer agent knows that the data was changed by another user, aborts the transaction, and notifies the client application that the updates failed.
6. If the data has not been changed (within the same transaction as Step 5), the AppServer then compares the Client-Out table to the Orig table. For each record within the Client-Out table that has been created, modified, or deleted, the AppServer makes the same changes to the data within the database.
There are variations on the approach suggested in the previous figure that provide similar results, and exactly how you vary this scheme will depend on your particular application requirements. For example, in Step 5, even if the AppServer finds a difference between the records in the Orig temp-table and the records in the database, it might not be necessary to abort the transaction. An alternative approach is to simply note which record has changed, find the corresponding record in the Client-Out temp-table returned to the AppServer, and skip that when applying the changes in Step 6. Only you can decide what approach is appropriate for your application.