Berkeley DB Reference Guide: Configuring locking
Description: Berkeley DB: An embedded database programmatic toolkit.
Keywords: embedded,database,programmatic,toolkit,b+tree,btree,hash,hashing,transaction,transactions,locking,logging,access method,access methods,java,C,C++

### Berkeley DB Reference Guide: Locking Subsystem |

# Configuring locking

The lock system is configured using the following interfaces:

>     DBENV->set_lk_conflicts
>     DBENV->set_lk_detect
>     DBENV->set_lk_max

The DBENV->set_lk_max interface specifies the number of locks that will be allocated in the locking subsystem. Selecting an appropriate value requires an understanding of your application and its databases. If the number of locks is too small, then requests for locks in an application will fail. If the number of locks is too large, then the locking subsystem will consume more resources than is necessary. It is better to err in the direction of allocating too many locks as increasing the number of locks does not require large amounts of additional resources.

For Btree and Recno access methods, you will need, at a minimum, one lock per level of the database tree. Unless keys are quite large with respect to the page size, neither Recno nor Btree database trees should be deeper than five levels. For the Queue access method you will need one lock per record accessed by a transaction plus one page lock. Also, for the Queue access method, deleted records that are skipped by a DB_NEXT or DB_PREV operation are not locked, and, if your application is using transactions then an operation will never use more than three locks at a time. For the Hash access method you will only need a single lock. For all access methods, you may need an additional lock for the access method metadata page, and you should assume an additional lock for every open cursor.

Finally, if your application is transactionally protected, you will need to multiple the maximum number of locks per operation by the number of operations performed during the life of the transaction. This value is maximally pessimistic, since it is possible, but not probable, that each operation will acquire new page locks by accessing pages that have not yet been accessed in the context of the transaction.

To estimate the total number of locks required for an application, estimate the maximum number of locks needed per transaction (if running with transactions) or operation (if running without transactions). Multiply this number by the maximum number of concurrent threads and processes you expect your application to support. Then, for good measure, double this estimate!

The DBENV->set_lk_detect function specifies that the deadlock detector should be run whenever a lock blocks. This option provides for rapid detection of deadlocks at the expense of potentially frequent invocations of the deadlock detector. On a fast processor with a highly contentious application, where response time is critical, this is a good choice. An argument to the DBENV->set_lk_detect function indicates which transaction to abort when a deadlock is detected. It can take on any one of the following values:

DB_LOCK_YOUNGEST
  Abort the most recently started transaction.
DB_LOCK_OLDEST
  Abort the longest lived transaction.
DB_LOCK_RANDOM
  Abort whatever transaction the deadlock detector happens to find first.
DB_LOCK_DEFAULT
  Use the default policy (currently DB_RANDOM).

In general, DB_LOCK_DEFAULT is probably the correct choice. If an application has long-running transactions, then DB_LOCK_YOUNGEST will guarantee that transactions eventually complete, but it may do so at the expense of a large number of aborts.

The alternative to using the DBENV->set_lk_detect interface is to run the deadlock detector manually, using the Berkeley DB lock_detect interface.

The DBENV->set_lk_conflicts function allows you to specify your own locking conflicts matrix. This is an advanced configuration option, and rarely necessary.

Copyright Sleepycat Software