MediumStateful DesignPython 3
Transactional KV Store
Implement nested in-memory transactions with read-your-writes, tombstones, commit, and rollback.
40m3 sample tests9 hidden tests
Implement TransactionalKV, an in-memory key/value store with nested transactions. An explicit tombstone must hide a lower-layer value after a transactional delete.
Requirements
set(key, value)writes a value.get(key)returns the visible value orNone.Noneis a valid stored value and must shadow lower layers, even thoughgetcan't distinguish it from absence.delete(key)removes the visible value.- Deleting a missing key is harmless.
begin()opens a transaction layer.commit()merges the current transaction into its parent layer or the base store.rollback()discards the current transaction.- Both control operations close only the innermost layer. An inner commit can still be undone by rolling back its parent.
- Reads inside a transaction must see writes and deletes from that transaction first.
- Deleting a key inside a transaction must hide lower-layer values until rollback or commit.
- Calling
commit()orrollback()without an active transaction raisesValueError.
Example
Nested layers should make deletion and rollback observable:
| Operation | Visible model | Reason |
|---|---|---|
Base set("model", "fast") | "fast" | Base value exists. |
Outer begin(); delete("model") | None | Tombstone hides the base value. |
Inner begin(); set("model", "strong") | "strong" | Inner write shadows the tombstone. |
Inner rollback() | None | Outer deletion becomes visible again. |
Outer rollback() | "fast" | Base value was never deleted. |
The smaller example below demonstrates the write-and-rollback path:
python
1store = TransactionalKV()
2store.set("model", "fast")
3store.begin()
4store.set("model", "strong")
5assert store.get("model") == "strong"
6store.rollback()
7assert store.get("model") == "fast"Constraints
- Keep it single-process and in memory, with sequential calls and one shared transaction stack.
- Treat values as opaque references. Transactions track
setanddelete; they don't undo in-place mutations to returned objects. - Preserve nested transaction semantics.
- Don't use a database library.
- Distinguish a missing layer entry from an explicit deletion marker.
Editor