Building Distributed
Applications
Using the Progress AppServer
Buffer Currency and NO-LOCK
If you try to find a record with NO-LOCK and that record is already located in a buffer, then depending on the exact nature of the request, Progress may not re-read the record from the database.
The fact that Progress does not always re-read NO-LOCK records may cause unexpected behavior in your distributed application. More specifically, although a record was updated within one session (Client or AppServer), that update may not be seen within another session if that record was previously read with NO-LOCK. There are two scenarios where this may occur. These scenarios are called currency conflicts to denote the fact that they involve a buffer whose contents is not current:
- Client-Server Currency Conflict
In this scenario, a client finds a record NO-LOCK, and then sends a request to an AppServer to update the same record. When the request finishes, the client attempts to find the same record. Because Progress may not re-read the record, the client buffer might contain the copy of the record before the update occurred rather than the updated copy of the record.
- Server-Server Currency Conflict
In this scenario, a client sends a request to an AppServer whose operating mode is stateless. The Application Server process who processes the request updates some record. The client then sends another request to the AppServer. This request happens to go to an Application Server process that is different then the one that processed the first request. The Application Server process attempts to find the same record that was updated using NO-LOCK. If the record was already stored in a buffer due to some previous clients request executed at this Application Server process, Progress may not re-read the record. When this occurs, the Application Server process buffer will contain the copy of the record before the update occurred rather than the updated copy of the record.
If resolving client-server or server-server currency conflicts is important to you, there are three general approaches that you can use:
Reading the Current Record
If you know exactly which buffer is out of date, use FIND CURRENT or GET CURRENT with NO-LOCK. The CURRENT keyword indicates to Progress that the record must be re-read.
Releasing the Record
Use the RELEASE statement on all buffers that may be out of date before the record is re-read. The RELEASE statement will clear the records from all buffers to which it is applied. At that point, all records that Progress reads will need to be read from the database because a buffer copy no longer exists.
Setting the —rereadnolock Parameter
The -rereadnolock parameter indicates to Progress that when an attempt is made to find a record NO-LOCK, even if the record is already in a buffer, then the record should be re-read from the database. Use it as a 4GL Client startup parameter to resolve Client-Server Currency Conflicts. Use it as an AppServer startup parameter via the Progress Explorer or by setting the
srvrStartupParam
property in theubroker.properties
file for the appropriate AppServer to resolve Server-Server Currency Conflicts.Note there are several things to keep in mind when using the —rereadnolock startup parameter:
- The -rereadnolock parameter has no affect on records that are being retrieved via RECID or ROWID. In that case, Progress will not re-read the record. It will use the copy of the record already stored in the buffer. If the most current version of the record is needed, then use the RELEASE statement on all buffers that contain a copy of the record before reading the record, or use FIND CURRENT or GET CURRENT statement to re-read the record.
- The -rereadnolock parameter has no affect on the behavior of the query cache used for a NO-LOCK query as specified via the CACHE n phrase of the DEFINE QUERY statement. If the record is in the cache, it will not be re-read regardless of whether -rereadnolock is set. To force the record to always be re-read set CACHE 0. Note that setting the cache size to zero (0) may significantly degrade performance if the database is being accessed across a network. Only set the cache size to zero (0) when it is critical to retrieve the most current version of a record.
- The -rereadnolock parameter has no affect on the behavior of the prefetch cache that is used by default when retrieving records NO-LOCK across the network. By default, when executing a CAN-FIND function, or the FIND, FOR, or OPEN QUERY statements on a database which is being accessed across a network, Progress fetches several records at a time, and stores those records within a prefetch cache. Progress will only sends a request to the database server to fetch more records if the requested record is not contained within the current prefetch cache. If the record is in this cache, a new copy of that record will not be read even if -rereadnolock is set. To eliminate this cache so that the most current version of the record is always read use the NO-PREFETCH keyword in the appropriate statements. Note that using the NO-PREFETCH keyword may significantly degrade performance. Only set NO-PREFETCH when it is critical to retrieve the most current version of a record.
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |