Release 10.1A: OpenEdge Application Server:
Developing AppServer Applications

> ## 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, OpenEdge may not reread the record from the database.

> The fact that OpenEdge does not always reread `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 OpenEdge may not reread 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 AppServer agent who processes the request updates some record. The client then sends another request to the AppServer. This request happens to go to an AppServer agent that is different then the one that processed the first request. The AppServer agent 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 AppServer agent, OpenEdge may not reread the record. When this occurs, the AppServer agent 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

> - Releasing the record

> - Setting the -rereadnolock parameter

> ##### 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 OpenEdge that the record must be reread.

> ##### Releasing the record

> Use the `RELEASE` statement on all buffers that may be out of date before the record is reread. The `RELEASE` statement will clear the records from all buffers to which it is applied. At that point, all records that OpenEdge 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 OpenEdge 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 reread from the database. Use it as a Progress 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 the `ubroker.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, OpenEdge will not reread 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 reread 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 reread regardless of whether `-rereadnolock` is set. To force the record to always be reread 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, OpenEdge fetches several records at a time, and stores those records within a prefetch cache. OpenEdge 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 © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095