Challenge #6c: Totally-Available, Read Committed Transactions

Now that you have data replicating between nodes from the Totally-Available, Read Uncommitted Transactions challenge, we’ll increase the difficulty by strengthening our consistency model to Read Committed.

Read Committed adds consistency guarantees while still being a relatively weak consistency model. In addition to G0, it also prohibits three additional anomalies:

  • G1a (aborted read): An aborted transaction T1 writes key x, and a committed transaction T2 reads that write to x.

  • G1b (intermediate read): A committed transaction T2 reads a value of key x that was generated by transaction T1 other than T1โ€™s final write of x.

  • G1c (circular information flow): A cycle of transactions linked by either write-read or read-write dependencies. For instance, transaction T1 writes x = 1 and reads y = 2, and transaction T2 writes y = 2 and reads x = 1

In summary, these ensure that changes made during a transaction are not visible to other transactions until they are committed.

Specification

Ensure your distributed key/value store implements a Read Committed consistency model while also preserving total availability.

Aborting transactions

To test G1a, you can abort a transaction by replying:

{
  "type":        "error",
  "in_reply_to": 1,  
  "code":        30,
  "text":        "The requested transaction has been aborted because of a conflict with another transaction. Servers need not return this error on every conflict: they may choose to retry automatically instead."
}

The Maelstrom code of 30 is txn-conflict. The in_reply_to should be the message ID of the request to be aborted.

This can be done with the Go client with:

return n.Reply(
    msg,
    map[string]any{
        "type": "error",
        "code": maelstrom.TxnConflict,
        "text": "txn abort",
    },
)

Evaluation

Build your Go binary as maelstrom-txn and run it against Maelstrom with the following command:

./maelstrom test -w txn-rw-register --bin ~/go/bin/maelstrom-txn --node-count 2 --concurrency 2n --time-limit 20 --rate 1000 --consistency-models read-committed --availability total โ€“-nemesis partition

If you’re successful, that’s amazing! You’ve made it to the end of the Fly.io Distributed Systems Challenge. ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰

If you’re having trouble, jump over to the Fly.io Community forum for help.

If you’ve helped others working on these challenges in the Community forum, we offer our sincere thanks. These are hard topics to wrap our brains around and we all need a hand from time to time.

  1. Read More About Echo
  2. Read More About Unique ID Generation
  3. Read More About Broadcast
  4. Read More About Grow-Only Counter
  5. Read More About Kafka-Style Log
  6. Read More About Totally-Available Transactions