Executing the Request
During the lifetime of a request, the request can finally be executed after the concurrency manager calls sequence_req
. In this section, we finally get to look at how the requests are executed.
These are the request types of the database:
- BeginTxn
- CommitTxn
- AbortTxn
- Get
- Put
Each command needs to implement an execute method. Here are its implementations:
BeginTxn
- BeginTxn simply creates a transaction record with the txn’s timestamp.
CommitTxn
-
CommitTxn first fetches the transaction record. If the transaction record is aborted, it returns an error.
-
Otherwise, it begins committing the transaction. Firstly, it needs to
perform a read refresh
to advance the read timestamp to the write timestamp. If you need a “refresher” on read refresh, look at
this page
.
- If the read refresh is unsuccessful, it returns a ReadRefreshError, which would restart the transaction.
- If read refresh is successful, it updates the transaction record to be committed.
-
Next, it resolves the uncommitted intent, which replaces it with a proper MVCC key value with the transaction’s commit timestamp.
-
Next, it releases the locks held by the transaction
-
Finally, it removes itself from the TxnWaitQueue in case it was queued
AbortTxn
- AbortTxn first makes sure the transaction record isn’t committed
- Next, it updates the transaction record to abort
- It then removes all uncommitted intents from the MVCC database
- Next, it releases the locks held by the transaction
- Finally, it removes itself from the TxnWaitQueue in case it was queued
Get
- Get first uses the read timestamp to perform a mvcc_get to retrieve the most recent value for the key.
- If mvcc_get returns an uncommitted intent, it checks if the request’s transaction and the intent’s transaction are the same. In that case, the transaction is reading its uncommitted write so it can proceed.
- Otherwise, Get returns a WriteIntentError
- Next, the function adds the key to the read sets to the transaction so that a read refresh can be performed later if the write timestamp gets bumped.
- Finally, it returns the value.
Put
- Put uses mvcc_put to attempt to put an uncommitted intent into the database.
- If mvcc_put is successful, it adds the uncommitted intent to the lock table by calling acquire_lock
- Otherwise, this means that an uncommitted intent was detected. Since there can only be one uncommitted intent for each key, the function returns a WriteIntentError