|
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 space is reset each time recovery is run. If you reach the end of your transaction ID space, shut down your applications and restart them after running recovery. 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 as the locks obtained for transactions and non-transactions can conflict.
Since 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. While 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 interfere with each other (e.g., 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 in such a manner that the deadlock detector will be unable to resolve 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.