Monedula

Scenario 04.2.1 · Transactional write: commit vs abort

Kafka transaction commit vs abort with read_committed

Transactions · Advanced · about 3 min · Apache Kafka 4.3

One partition, two transactions: commit makes the batch visible to read_committed; abort marks the range aborted and a read_committed consumer skips it entirely.

Run this scenario in the playground

abort · range skipped. t+4.000s

abort_transaction records the range [2,4) in abortedRanges and releases the LSO PAST it to 4. The read_committed consumer advances its position over the range but delivers NONE of those records - the aborted batch is discarded. The HW advanced for both batches; only commit-vs-abort decided what is visible.

Open at this step: step 7, abort · range skipped

What you start with

The atom of a Kafka transaction shown twice on one partition while a read_committed consumer watches: one transaction that commits and one that aborts. Records are physically appended (the high-watermark advances) in both cases - only the Last Stable Offset (LSO) and read_committed delivery tell them apart.

Step by step

  1. Cluster ready · read_committed t+0.000s One partition (RF 3, min.ISR 2), a transactional producer, and a read_committed consumer. read_committed only delivers records up to the Last Stable Offset (LSO) - never records inside an open or aborted transaction. Open at this step: step 1, Cluster ready · read_committed
  2. begin txn 1 t+0.100s begin_transaction moves the producer to `ongoing`. This is client-side only: the coordinator learns of the transaction, and starts its timeout, when the first partition is added. Open at this step: step 2, begin txn 1
  3. Produced · uncommitted t+1.100s Two records were appended and replicated - the high-watermark advanced to 2, so they are durable. But the LSO stays pinned at 0: the records are physically in the log yet uncommitted, so a read_committed consumer cannot see them. Open at this step: step 3, Produced · uncommitted
  4. commit · LSO advances t+1.900s commit_transaction writes a commit marker and the LSO advances to the high watermark (2), so the read_committed consumer advances to 2. In Kafka the marker is a control record with its own offset (2 here), so the log end, LSO and position would be 3; the simulator gives markers no offset. Open at this step: step 4, commit · LSO advances
  5. begin txn 2 t+2.400s A second transaction opens on the same partition. Same starting point: records will append but stay invisible until this txn resolves. Open at this step: step 5, begin txn 2
  6. Produced · uncommitted t+3.100s Two more records append (HW = 4), again held below the LSO (still 2). So far this is identical to txn 1 - the raw log cannot yet tell a doomed batch from a good one. Open at this step: step 6, Produced · uncommitted
  7. abort · range skipped t+4.000s abort_transaction records the range [2,4) in abortedRanges and releases the LSO PAST it to 4. The read_committed consumer advances its position over the range but delivers NONE of those records - the aborted batch is discarded. The HW advanced for both batches; only commit-vs-abort decided what is visible. Open at this step: step 7, abort · range skipped

The takeaway

Committing advances the LSO so read_committed can read the batch; aborting writes an abort marker, records the aborted offset range and releases the LSO past it, so a read_committed consumer steps over the aborted records and delivers none of them.

Configs in this scenario

Embed this scenario

Paste this into a blog post, a course page or your team's docs. The scenario plays inside your page, and the link under it points readers to this walkthrough.

<iframe src="https://monedula.dev/kafka-simulator/embed/?scenario=04.2.1" title="Kafka Simulator: Transactional write: commit vs abort" width="100%" height="520" style="border:1px solid #d0d0d0;border-radius:8px" loading="lazy"></iframe>
<p><a href="https://monedula.dev/kafka-simulator/scenarios/txn-commit-vs-abort/">Kafka transaction commit vs abort with read_committed</a></p>

Further reading

Apache Kafka documentation

More in Transactions

All scenarios