Deadlock detection using timers
Lock and transaction timeouts may be used in place of, or in addition to, regular deadlock detection. If lock timeouts are set, lock requests will return DB_LOCK_NOTGRANTED from a lock call when it is detected that the lock’s timeout has expired, that is, the lock request has blocked, waiting, longer than the specified timeout. If transaction timeouts are set, lock requests will return DB_LOCK_NOTGRANTED from a lock call when it has been detected that the transaction has been active longer than the specified timeout.
If lock or transaction timeouts have been set, database operations will return DB_LOCK_DEADLOCK when the lock timeout has expired or the transaction has been active longer than the specified timeout. Applications wanting to distinguish between true deadlock and timeout can use the DB_ENV->set_flags() configuration flag, which causes database operations to instead return DB_LOCK_NOTGRANTED in the case of timeout.
As lock and transaction timeouts are only checked when lock requests first block or when deadlock detection is performed, the accuracy of the timeout depends on how often deadlock detection is performed. More specifically, transactions will continue to run after their timeout has expired if they do not block on a lock request after that time. A separate deadlock detection thread (or process) should always be used if the application depends on timeouts; otherwise, if there are no new blocked lock requests a pending timeout will never trigger.
If the database environment deadlock detector has been configured with the DB_LOCK_EXPIRE option, timeouts are the only mechanism by which deadlocks will be broken. If the deadlock detector has been configured with a different option, then regular deadlock detection will be performed, and in addition, if timeouts have also been specified, lock requests and transactions will time out as well.
Lock and transaction timeouts may be specified on a database environment wide basis using the DB_ENV->set_timeout() method. Lock timeouts may be specified on a per-lock request basis using the DB_ENV->lock_vec() method. Lock and transaction timeouts may be specified on a per-transaction basis using the DB_TXN->set_timeout() method. Per-lock and per-transaction timeouts supersede environment wide timeouts.
For example, consider that the environment wide transaction timeout has been set to 20ms, the environment wide lock timeout has been set to 10ms, a transaction has been created in this environment and its timeout value set to 8ms, and a specific lock request has been made on behalf of this transaction where the lock timeout was set to 4ms. By default, transactions in this environment will be timed out if they block waiting for a lock after 20ms. The specific transaction described will be timed out if it blocks waiting for a lock after 8ms. By default, any lock request in this system will be timed out if it blocks longer than 10ms, and the specific lock described will be timed out if it blocks longer than 4ms.