Bringing together the Apache Cassandra experts from the community and DataStax.

Want to learn? Have a question? Want to share your expertise? You are in the right place!

Not sure where to begin? Getting Started

 

question

kavithakaran avatar image
kavithakaran asked ·

Why is a LWT read committing an uncommitted transaction?

I am reading Cassandra: The Definitive Guide, 3rd edition. It has the following text:

"The serial consistency level can apply on reads as well. If Cassandra detects that a query is reading data that is part of an uncommitted transaction, it commits the transaction as part of the read, according to the specified serial consistency level."

Why a read is committing an uncommitted transaction and doesn't it interfere with ability of the writer to rollback?

UPDATE

Subsequent questions:

When you say "It is committing a transaction from another in-flight mutation when it performed the read", do you mean that "Other in-flight transaction has progressed past the "Propose/Accept" stage by the initiator of that transaction.

If that is case,

- Can I say, once a transaction has gone past "Propose/Accept" stage, it does not matter who performs "Commit/Acknowledge" (.ie initiator of that transaction or some other read) because even the initiator of that transaction can't rollback after 3rd stage

- Regarding isolation, I thought read will return the previously committed values. but here the read seems to detect the "uncommitted read" and tries to commit it and return it. Isn't this against Isolation guarantee?

- what happens if the read was not able to commit, will it fail or will it return the previously committed values?

lightweight transactions
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

1 Answer

Erick Ramirez avatar image
Erick Ramirez answered ·

For clarification, the serial read is not committing its own LWT write. It is committing a transaction from another in-flight mutation when it performed the read. This takes place because in Cassandra, a write is not considered successful unless it is persisted to disk.

To be clear, the serial read (in the read-before-write) is not making a new addition or update -- it is just persisting an uncommitted transaction so it can provide guarantees such as "the data exists" (IF EXISTS) or not (IF NOT EXISTS).

For example, Tom updated value X for partition Y. While that's taking place, Harry performs a conditional update for partition Y if value X exists. While checking the condition if value X exists for Harry's request, Cassandra finds that Tom's update is uncommitted so persists it to disk before confirming that value X exists.

"Committed" means that a mutation (INSERT, UPDATE or DELETE) is persisted (saved) to disk. "Uncommitted" is when a mutation is still in the process of being saved to the commitlog.

The reason this is important is that the serial read phase of the LWT read-before-write cannot say a value exists (for IF EXISTS conditionals) until that value is saved to disk. Until a mutation is written to the commitlog, it's not "successful" or doesn't exist yet (uncommitted).

If you're interested, all the phases of LWTs are explained in the blog post Lightweight Transactions in Cassandra. Cheers!

8 comments Share
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Thank you for the answer.


When you say "It is committing a transaction from another in-flight mutation when it performed the read", do you mean that "Other in-flight transaction has progressed past the "Propose/Accept" stage by the initiator of that transaction.


If that is case,

- Can I say, once a transaction has gone past "Propose/Accept" stage, it does not matter who performs "Commit/Acknowledge" (.ie initiator of that transaction or some other read) because even the initiator of that transaction can't rollback after 3rd stage

- Regarding isolation, I thought read will return the previously committed values. but here the read seems to detect the "uncommitted read" and tries to commit it and return it. Isn't this against Isolation guarantee?

- what happens if the read was not able to commit, will it fail or will it return the previously committed values?



0 Likes 0 · ·

@kavithakaran That's exactly the point I'm trying to make -- the "other" in-flight transaction isn't related to the LWT you're concerned about. Think of it as "there happens to be another uncommitted write" already in progress when your LWT was doing the read-before-write.

For example, Tom updated value X for partition Y. While that's taking place, Harry performs a conditional update for partition Y if value X exists.

While reading if value X exists for Harry's request, Cassandra finds that Tom's update is uncommitted so persists it to disk before confirming that value X exists. Does that make sense? :)

0 Likes 0 · ·
kavithakaran avatar image kavithakaran Erick Ramirez ♦♦ ·

`Tom updated value X for partition Y` . Cassandra finds that Tom's update is uncommitted so persists it to disk. If Tom updating value X for partition is not another LWT in progress but a normal transaction, why do we call it commit? Isn't that called read repair?

0 Likes 0 · ·
Show more comments