Transactions are identified uniquely by 32-bit unsigned integers. The high-order bit of the transaction ID is reserved (and defined to be 1), resulting in just over two billion unique transaction IDs. Each time that recovery is run, the beginning transaction ID is reset with new transactions being numbered, starting from 1. This means that recovery must be run at least once every two billion transactions.
It is possible that some environments may need to be aware of this limitation. Consider an application performing 600 transactions a second for 15 hours a day. The transaction ID space will run out in roughly 66 days:
2^31 / (600 * 15 * 60 * 60) = 66
Doing only 100 transactions a second exhausts the transaction ID space in roughly one year.
The transaction ID name space is initialized each time a database environment is created or recovered. If you reach the end of the transaction ID name space, it must be handled as if an application or system failure occurred. The most recently allocated transaction ID is the st_last_txnid value in the transaction statistics information, and is displayed by the db_stat utility.
When using transactions, cursors are localized to a single transaction. That is, a cursor may not span transactions, and must be opened and closed within a single transaction. In addition, intermingling transaction-protected cursor operations and non-transaction-protected cursor operations on the same database in a single thread of control is practically guaranteed to deadlock because the locks obtained for transactions and non-transactions can conflict.
Because transactions must hold all their locks until commit, a single transaction may accumulate a large number of long-term locks during its lifetime. As a result, when two concurrently running transactions access the same database, there is strong potential for conflict. Although Berkeley DB allows an application to have multiple outstanding transactions active within a single thread of control, great care must be taken to ensure that the transactions do not block each other (for example, attempt to obtain conflicting locks on the same data). If two concurrently active transactions in the same thread of control do encounter a lock conflict, the thread of control will deadlock so that the deadlock detector cannot detect the problem. In this case, there is no true deadlock, but because the transaction on which a transaction is waiting is in the same thread of control, no forward progress can be made.
Copyright Sleepycat Software