Read committed is a consistency model which strengthens Read Uncommitted by preventing dirty reads: transactions are not allowed to observe writes from transactions which do not commit.
Read committed is a transactional model: operations (usually termed “transactions”) can involve several primitive sub-operations performed in order. It is also a multi-object property: operations can act on multiple objects in the system.
Read committed can be totally available: in the presence of network partitions, every node can make progress. Without sacrificing availability, you can also ensure that transactions effects are observed together by choosing the stronger Monotonic Atomic View. For performance, you may wish to allow dirty reads, and relax to Read Uncommitted.
Note that read committed does not impose any real-time constraints. If process A completes write w, then process B begins a read r, r is not necessarily guaranteed to observe w. For a transactional model that provides real-time constraints, consider strict serializability.
Moreover, read committed does not require a per-process order between transactions. A process can observe a write, then fail to observe that same write in a subsequent transaction. In fact, a process can fail to observe its own prior writes, if those writes occurred in different transactions.
<aside> 💡 not requre a per-process order between transactions
即使在同一个 process 内也不保证任何跨事务的顺序,一个 process 的后一个事务的读可能看不见上一个事务的写。
</aside>
Like Serializability, read committed allows Pathological Ordering . For instance, a read commmitted database can always return the empty state for any reads, by appearing to execute those reads at time 0. It can also discard write-only transactions by reordering them to execute at the very end of the history, after any reads. Operations like increments can also be discarded, assuming the result of the increment is never observed. Luckily, most implementations don’t seem to take advantage of these optimization opportunities.
The ANSI SQL 1999 spec specifies repeatable read by disallowing phenomenon P1:
P1 (“Dirty read”): SQL-transaction T1 modifies a row. SQL-transaction T2 then reads that row before T1 performs a COMMIT. If T1 then performs a ROLLBACK, T2 will have read a row that was never committed and that may thus be considered to have never existed.
However, as Berenson, Bernstein, et al observed, the ANSI specification allows multiple intepretations, and one of those interpretations (the "anomaly interpretation) still admits nonserializable histories for “serializable” systems. Instead, we prefer Adya’s formalization of transactional isolation levels, which provides a concise definition of the preventative interpretation. In this model, read committed prohibits:
$P0(Dirty Write): w_1(x)...w_2(x)$:两个 tx 同时修改了某个数据,然后其中一个 tx 执行回滚,无法确认该回滚到什么值。(P0 Dirty Write)
$P1(Dirty Read): w_1(x)...r_2(x)$:读未提交
but allows:
$P2(Fuzzy Read): r_1(x)...w_2(x)$:两次读到的值不一致(不可重复读)
$P3(Phantom): r_1(P)...w_2(y\ in\ P)$:幻读,两次读到的数据量不一致。
Here w denotes a write, r denotes a read, and subscripts indicate the transaction which executed that operation. The notation “…” indicates a series of micro-operations except for a commit or abort. P indicates a predicate.