···3939The client chooses a `BeginBuffer` server and sends a `get_read_version()` request.
40404141The `BeginBuffer` batches a set of requests before sending its own request for a read version to the `Sequencer`.
4242-The `Sequencer` replies with a strictly monotonic read version guaranteed to be higher than any committed version
4242+The `Sequencer` replies with a read version guaranteed to be greater than or equal to any committed version
4343(this ensures strict serializability of transactions).
4444Additionally, the `BeginBuffer` sends requests to the fellow `TLog` servers from its generation asking whether any of them have been locked,
4545which would indicate a recovery taking place.
···49495050Before performing a read, the client needs to ask a `CommitBuffer` for information about the relevant shard and where it's stored.
5151This shard information can be aggressively cached as shards are moved rarely.
5252-If a Storage server turns out to no longer be serving the requested shard (i.e. the cache is stale),
5252+If a `Storage` server turns out to no longer be serving the requested shard (i.e. the cache is stale),
5353the client will ask the `CommitBuffer` for updated shard information.
54545555To perform reads, the client sends read requests to `Storage` servers.
···5757which is needed to prevent reads of uncommitted data following a recovery.
5858Reads are effectively performed against a consistent snapshot of the database at the read version.
59596060-Reads which cross shard boundaries are split and sent to their respective Storage servers.
6060+Reads which cross shard boundaries are split and sent to their respective `Storage` servers.
6161The results are joined.
62626363When reads are performed, the keys or key ranges read are tracked interally as read conflicts.
···7171This may seem redundant (we already have the writes themselves),
7272but in some cases advanced clients may choose to manipulate the write conflicts independently to improve performance or selectively weaken consistency guarantees.
7373However, such manipulation is dangerous and not generally recommended.
7474+7575+## Committing
7676+7777+To commit a transaction, the client gathers up the read version, read conflicts, write conflicts, and writes and sends them to a `CommitBuffer`.
7878+7979+The `CommitBuffer` batches committed transactions.
8080+Once a batch is ready, it first requests a commit version from the `Sequencer`.
8181+The `Sequencer` replies with a commit version which is guaranteed to be greater than any previous committed version (strictly monotonic).
8282+8383+The `CommitBuffer` then sends the transactions' read versions, commit versions, read conflicts, and write conflicts to the `Resolver`.
8484+The `Resolver` performs concurrency control;
8585+specifically, for each transaction it checks whether the keys and ranges read by that transaction at its read version are unchanged at its commit version.
8686+If any of the data read by the transaction was changed (by another transaction) during its execution, that transaction is rejected.
8787+This ensure strict serializability of transactions.
8888+8989+Mutations from the surviving transactions are then combined into a single batch,
9090+as from this point on the distinction between transactions within a batch no longer exists.
9191+The transactions are then sliced:
9292+the CommitBuffer consults its shard map (which is always perfectly consistent)
9393+and determines which `Storage` teams are responsible for each mutation.
9494+Each mutation is tagged with the `Storage` teams it's destined for,
9595+and the mutations are then grouped together by their corresponding `TLog` teams.
9696+9797+A commit request containing the relevant tagged mutations and the commit version is sent to each `TLog` server.
9898+An empty request is still sent to a `TLog` even if it has no mutations, as it still needs to learn of the committed version.
9999+The requests are sent in parallel.
100100+101101+Once *every* TLog has returned,
102102+the `CommitBuffer` accordingly returns to all of the clients in the batch.
103103+104104+## Storage peeks logs
105105+106106+Outside of the commit path,
107107+`Storage` servers "peek" logs for their team by sending peek requests to their corresponding `TLog` servers.
108108+The `Storage` servers receive logs in perfect commit version order and apply them to their storage engines so that they can serve reads.