Benefits and Risks of U_VERSION
U_VERSION is a special field that Uniface uses during update or delete operations to ascertain whether a row of data has been changed by another process. If the value of U_VERSION has not changed, Uniface assumes that nothing else in the row has changed. Without U_VERSION, Uniface checks the value of every field in the row for changes.
Benefits
The primary benefit of using U_VERSION is increased performance. Uniface can avoid checking any fields that follow U_VERSION in the entity definition, so it saves some processing. However, the actual savings in processing are probably minimal unless the following conditions are met:
- Using a cautious (default) or optimistic locking strategy. Under paranoid locking,
data locks are set as soon as the data is retrieved, so the data cannot be changed by other
processes in the meantime.
Under cautious or optimistic locking, Uniface must re-read a row that is being modified to apply a lock. Under cautious locking, this happens when row is first modified. Under optimistic locking, the check occurs just before updating the database.
- U_VERSION is placed very close to the beginning of the field definitions for the entity, preferably immediately following the primary key field(s). Otherwise, Uniface compares all the fields until it gets to the U_VERSION field.
- There are a large number of fields or some very large fixed length or BLOB fields in the entity definition following U_VERSION. If there is only a small amount of data after the U_VERSION field, the processing saved is negligible.
Risks
Using U_VERSION can present a risk to data integrity in a high-transaction or multi-tool environment. U_VERSION should not be used if any of the following circumstances apply:
- Transaction rate is very high and there are common rows being updated by many
application users simultaneously. This is because the value of U_VERSION is always a printable
ASCII character, that is, a value between ASCII 32 (Space) and ASCII 126. Each time Uniface updates
a row, it increments the value of U_VERSION, so the value continually cycles through the set of
printable ASCII characters.
In a high-transaction environment in which common data is frequently updated, it is possible that the value of U_VERSION cycles through to the same value it had before. In this case, Uniface assumes no changes have been made and updates the row, overwriting all the intermediate changes imposed by other processes. If this should happen, the integrity of the data is lost without a trace of the problem.
- Data access components are implemented in a technology other than Uniface. In this case, do not add U_VERSION to the entity definition.
- Persistent data layer is accessed directly instead of via the data access components
of the applicable component package. In this case, the U_VERSION field is not updated, even if
present.
For example, suppose you have a package with Uniface data access components and U_VERSION is applied. An HTML component retrieves a row which it intends to modify via the Uniface data access component. Shortly thereafter, a service component written in C++ retrieves the same row directly, ignoring the data access layer. The C++ component then modifies, locks, stores, and commits the row to the DBMS. When the HTML component submits its data, the Uniface data access component attempts to modify the row, it retrieves the row again and checks for changes. If U_VERSION has not changed, it will not check any later fields in the row. However, the C++ component did not modify U_VERSION. It only modified a description field which comes after U_VERSION. Uniface ignores the change that has been made to the description and updates the row with its changes, overwriting the change made by the C++ component.