1. The transaction explicitly takes a snapshot of all values in
the readset and writeset. Real systems use a multi-versioned database to access the
correct data.
1. Reads are satisfied from the snapshot, *or writes from the same transaction*.
2. Written values are tracked and added to a writebuffer
rather than being written to the relation.
3. At commit time, we check to see whether data for which we have updates in our writebuffers
has been changed in the relation by any other transaction. Since our system does not currently have
explicit versioning,
we approximate this by checking to see whether the any *values* of the data we are writing
have changed.
Logically, you will have to add three pieces of state to the
transaction's initialization:
-*snapshot*: a `dict` of database values indexed by `(attr, id)`
-*writeBuffer*: an ordered list of values to be written out at
successfull commit
-*writeset*: a set describing which data has been modified. This can be
extracted from the writeBuffer at commit time, and so does not have to
be tracked explicitly.
You do not have to structure your data this way, and there is some
redundancy in the above.
### Testing
Use `python3 testing.py` to test your implementation locally prior to
gradescope submission. Remove `relation1` before testing:
```
rm relation1 ; python3 testing.py
```
### Submission
Submit the modified `transactions.py` file to [Gradescope](https://www.gradescope.com/courses/811728/assignments/4828403/review_grades).
You should not change any other files.
<sup>1</sup>Thomson, A., Diamond, T., Weng, S. C., Ren, K., Shao, P., & Abadi, D. J. "Calvin: fast distributed transactions for partitioned database systems." *Proceedings of the 2012 ACM SIGMOD International Conference on Management of Data*. 2012.