Transient vs. Persistent ITIM_ERR (160) Errors
Multi-user interference error 160 is not always fatal, however, you need to understand what it implies.
It is certainly possible to encounter a 160 (ITIM_ERR) error during 'normal' processing. This error really indicates 'multi-user interference', typically, a timing issue when reading records undergoing concurrent update by multiple users.
Here is background information on what exactly leads to a 160 error being raised. When a record is looked up by key value, we go to the record offset in the data file referenced by the key value in the index. After reading that record, we recompute the key value from the current record contents. If that value differs from the original key value used to find it, we send back the 160 error indicating a potential out of sync record.
This condition can either be temporary, for example, in a highly concurrent usage where multiple clients are updating the same record, or persisted, for example, when a 'bad' index is encountered. (An old backup copy, or a corrupt index say from an application crash during an update and only one of the values - index or data - were properly stored.) Even with proper locking, under highly concurrent updates there is always a tiny window where the index could be updated slightly ahead of the data. A persisted 160 is noted when even after application restart the same index lookup generates the 160.
For temporary conditions, simply retrying the read operation is usually sufficient. In fact, internally, c-tree attempts 10 re-reads in very rapid succession for you just be sure the situation isn't transient at that moment. However, that retry loop may be too quick in most instances. You can configure these automated retry parameters.
ITIM_RETRY_LIMIT
https://docs.faircom.com/doc/ctserver/#48620.htm
ITIM_RETRY_DEFER
https://docs.faircom.com/doc/ctserver/#48619.htm
For persisted cases, the index would need to be rebuilt. That should never be necessary for files under c-tree transaction control. However, in non-transaction environments, this is always a possibility should the application fail for any reason during update.
Here is background information on what exactly leads to a 160 error being raised. When a record is looked up by key value, we go to the record offset in the data file referenced by the key value in the index. After reading that record, we recompute the key value from the current record contents. If that value differs from the original key value used to find it, we send back the 160 error indicating a potential out of sync record.
This condition can either be temporary, for example, in a highly concurrent usage where multiple clients are updating the same record, or persisted, for example, when a 'bad' index is encountered. (An old backup copy, or a corrupt index say from an application crash during an update and only one of the values - index or data - were properly stored.) Even with proper locking, under highly concurrent updates there is always a tiny window where the index could be updated slightly ahead of the data. A persisted 160 is noted when even after application restart the same index lookup generates the 160.
For temporary conditions, simply retrying the read operation is usually sufficient. In fact, internally, c-tree attempts 10 re-reads in very rapid succession for you just be sure the situation isn't transient at that moment. However, that retry loop may be too quick in most instances. You can configure these automated retry parameters.
ITIM_RETRY_LIMIT
https://docs.faircom.com/doc/ctserver/#48620.htm
ITIM_RETRY_DEFER
https://docs.faircom.com/doc/ctserver/#48619.htm
For persisted cases, the index would need to be rebuilt. That should never be necessary for files under c-tree transaction control. However, in non-transaction environments, this is always a possibility should the application fail for any reason during update.