Skip to content

Cassandra: unconditional PutItem on one key of a GSI table answers TransactionConflictException under contention #802

Open

Description

@LeeroyHannigan

What happens

32 writers, each with its own client and client retries off, send 63 unconditional PutItem calls each (2,016 in all) on one key of a table with a GSI. On the Cassandra backend some of the puts answer 400 TransactionConflictException:

The test is tests/test_put_item_gsi_contention.py::test_unconditional_puts_on_one_key_of_a_gsi_table_commit_or_are_shed, added by #487. On SQLite, PostgreSQL and MongoDB the same test passes.

What DynamoDB does

Measured on 2026-10-21 in us-east-1 with client retries off (the measurements in #431's description): 32 writers x 63 rounds of racing unconditional PutItem on one key of a GSI table and of a stream table answered 200 to all 2,016 calls of each, and the last writer's item was stored with its index entry.

Expected

An unconditional PutItem that loses a race on its key to another unconditional PutItem is retried inside the server until it commits, so the client never sees TransactionConflictException for this shape. The Cassandra write path gives up after its retry budget and returns the conflict to the client instead.

Related

#426 is the same answer on the MongoDB backend, which #487 changes to a commit or, after 10 s of contention, a 503. #424 changes how the Cassandra write paths stamp their index rows and retry a lost race. #487 skips this test on Cassandra until this is fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions