Non-Repeatable Reads
Non-repeatable reads a feature that can allow for better performance by relaxing some of the ACID properties of a database. To be fully ACID, locks need to be held whenever data is read from the database to ensure that the data being read is the most up-to-date and correct data. However, locking data all the time has a performance impact and, especially if the data doesn't change very often, may not be necessary. Non-repeatable reading allows data to be read without holding locks on the data. These opens up the possibility that the data read may not be the most recent data, but this is often a worthwhile trade-off.
When pages are read into the cache, along with the data, a timestamp for the file is included. This timestamp gets updated whenever the file is modified. If another page is then read into the cache from the same file but with a newer timestamp, the system can know that the file has been changed since the first page was read. This mechanism allows the system to know that some of the data being read may be out of date with previously read data.
These capabilities allow the system to make sure that within one function call, all access to the database is consistent with itself - meaning multiple page accesses are internally consistent: either all older or all up-to-date - never a combination. However between function calls it is possible to see different data. For example it might be possible to access a record via an index only to find that the record has been deleted or even not yet created when attempting to read data from that record or accessing another record via a set from the first record.
In addition, it is possible that all the database being accessed is already in the cache. If this was left this way, it would be possible to never see any new or changed data. To avoid this, the system has a timeout where it will automatically check the timestamp of files after a specified period of time. If the timestamp for a particular file has been updated since the cache was loaded, all pages for that file are discarded and re-read. By default this timeout period is 1000 milliseconds (1 second), but this can be adjusted via the d_drrefresh()
function.
By default non-repeatable reading is enabled for all read functions for performance reasons, but some applications may require that all the ACID properties be fully in effect. In that case the application would want to apply locks before any reads. In order to facilitate such applications, there is a database open mode that will cause the reading functions to generate an error if they are called outside the presence of the required locks. This mode is called 'strict' mode and is represented by an 'S' (capital 's') for shared read-update mode and by an 'R' (capital 'r') for read-only mode. In these modes non-repeatable reading is completely disabled.