Exercise 1: A Read-Only Transaction Never Conflicts — Possible Solution ==================================================================== THE TEST ------------------------------ store = MVCCStore(detect_conflicts=True) setup = store.begin(); store.write(setup, 'x', 5); store.commit(setup) reader = store.begin() _ = store.read(reader, 'x') # read only, no write writer = store.begin() store.write(writer, 'x', 999) store.commit(writer) # a real concurrent commit happens store.commit(reader) # does this conflict? final = store.read(store.begin(), 'x') RESULT ------------------------------ read-only transaction's own commit() succeeded with no conflict, final value: 999 The reader's own commit() call raises nothing at all, even though a genuinely newer commit (writer's own, changing x to 999) landed after the reader's snapshot was captured. WHY A READ-ONLY TRANSACTION CAN NEVER TRIGGER THE CHECK ------------------------------ commit()'s own conflict-detection loop is: for row_id in self.txn_pending_writes[txn_id]: current = self._current_committed_version(row_id) if current is not None and current.created_ts > snapshot: raise WriteConflict(...) This loop iterates over self.txn_pending_writes[txn_id] -- the set of rows THIS transaction has written to. A transaction that only ever calls read(), never write(), has an empty pending-writes dictionary for the entire duration of its own lifetime. Iterating over an empty dictionary runs the loop body zero times, so the conflict check has literally nothing to examine, and commit() falls straight through to the unconditional part of the function (which, for a transaction with no pending writes, also does nothing meaningful -- there's nothing to assign a new created_ts to). WHY THIS IS CORRECT, NOT JUST CONVENIENT ------------------------------ The whole point of the first-committer-wins check is to protect against a transaction committing a write that was computed from data that's since become stale. A transaction that never writes anything never has a computed value that could BE stale in a way that matters -- it read whatever was true as of its own snapshot, used that information for whatever purpose (display it, make a decision, whatever), and that's the end of its own involvement with the data. There is no "write built on old information" for a read-only transaction to protect against, so requiring one to pass a conflict check would be enforcing a rule that doesn't apply to it at all. WHY THIS WORKS AS AN ANSWER ------------------------------ Verifying a read-only transaction's own commit() genuinely never raises, even in the presence of a real concurrent write to the exact same row it read, confirms the conflict check is scoped specifically to WRITES this transaction is trying to make durable -- not to anything it merely observed along the way.