Applications configuring timestamps can use the WT_SESSION::prepare_transaction call as the pre-commit step in the implementation of a two-phase commit protocol. (WiredTiger currently only permits transactions to be prepared when timestamps are in use.)
The WT_SESSION::prepare_transaction method assigns a prepare timestamp to the transaction, which will be used for visibility checks until the transaction is committed or aborted. Once a transaction has been prepared no further data operations are permitted, and the transaction must next be resolved by calling WT_SESSION::commit_transaction or WT_SESSION::rollback_transaction. Calling WT_SESSION::prepare_transaction only guarantees that a subsequent WT_SESSION::commit_transaction will succeed and specifically does not guarantee the transaction's updates are durable.
If a read operation encounters an update from a prepared transaction, the error WT_PREPARE_CONFLICT will be returned indicating it is not possible to choose a version of data to return until the prepared transaction is resolved. Retrying such failed operations is reasonable, assuming prepared transactions are expected to be resolved quickly.
Both a commit_timestamp
and a durable_timestamp
must be specified when committing a prepared transaction. The job of the durable_timestamp
is to allow a prepared transaction to be predictably included or excluded from a checkpoint. For non-prepared transactions, the commit timestamp controls both transaction update visibility and durability. For prepared transactions, the durable timestamp separately controls the durability, that is, checkpoint uses the durable timestamp of the prepared transaction for persisting a transaction's updates rather than the commit timestamp.
Prepared transactions are limited to a single commit timestamp, which can only be set after the transaction has successfully prepared. The prepare timestamp can be set at any point in the transaction's lifecycle prior to preparing it; doing so does not itself prepare the transaction but does oblige the application to prepare it before committing.
The durable timestamp can only be set after the transaction has been prepared and a commit timestamp set, or as part of transaction commit. The durable
timestamp provides input into the system's all_durable
timestamp.
MongoDB specifies different commit and durable timestamps because prepared transactions are higher-level MongoDB operations, requiring cluster-level consensus on durability. Applications without similar requirements for prepared transactions should set the durable and commit timestamps to the same time.
The WT_SESSION::begin_transaction method includes the ignore_prepare
configuration. Setting the ignore_prepare
configuration to true causes readers to ignore prepared transactional values, that is, returning read values as if the prepared transaction didn't exist. This prevents readers from seeing the WT_PREPARE_CONFLICT error, returning the data as it was before the transaction was prepared. For this reason, applications using ignore_prepare
cannot rely on repeatable reads, as the same read after the prepared transaction is resolved could return a different value. Additionally, setting the ignore_prepare
configuration also causes the transaction to be read-only, and attempts to update items in the transaction will fail.
ignore_prepare
configuration can also be set to force
, which not only causes readers to ignore prepared transactions, but also allows the transaction to make updates. This can cause data inconsistency problems with the commit or rollback of the prepared transaction, or the disappearance of a prepared update by overwriting it.