Uploaded image for project: 'Apache Cassandra'
  1. Apache Cassandra
  2. CASSANDRA-18988

Updating the column of a non-existent row in an Accord transaction results in Atomicity violation

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Normal
    • Resolution: Not A Problem
    • 5.x
    • Accord
    • None

    Description

      System configuration and information:

      Single node Cassandra with Accord transactions enabled running on docker

      Built from commit: a7cd114435704b988c81f47ef53d0bfd6441f38b

      CQLSH: [cqlsh 6.2.0 | Cassandra 5.0-alpha2-SNAPSHOT | CQL spec 3.4.7 | Native protocol v5]

       

      Steps to reproduce in CQLSH:

      CREATE KEYSPACE accord WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = true;
      CREATE TABLE accord.accounts (
          partition text,
          account_id int,
          balance int,
          PRIMARY KEY (partition, account_id)
      ) WITH CLUSTERING ORDER BY (account_id ASC);
      
      BEGIN TRANSACTION
          INSERT INTO accord.accounts (partition, account_id, balance) VALUES ('default', 0, 100);
          INSERT INTO accord.accounts (partition, account_id, balance) VALUES ('default', 1, 100);
      COMMIT TRANSACTION;

      atomicity bug happens after executing the following statement:

      Based on Cassandra documentation regarding the use of UPDATE statements, I expect the result of this transaction to be the insertion of a new account ({ account_id: 3, balance: 10 }). The total balance across the three (3) accounts should be maintained (200). After executing the below transaction, the total number of accounts remains at two (2) and the total balance drops to 190. Basically, it appears as if only one half of the transaction proceeds.

      BEGIN TRANSACTION
          UPDATE accord.accounts
          SET balance -= 10
          WHERE
            partition = 'default'
            AND account_id = 1;
          UPDATE accord.accounts
          SET balance += 10
          WHERE
            partition = 'default'
            AND account_id = 3;
      COMMIT TRANSACTION;

      Bug / Error:
      ======================================================================

      The result of performing a table read after executing the buggy transaction is:

       partition | account_id | balance
      -----------+------------+---------
         default |          0 |     100
         default |          1 |      90
      

      Note that the above transactions are not possible without a transaction block because only counter type columns can be updated with += or -= syntax in normal (non-transactional) cql statements. Using counter type columns also results in a separate, related bug: CASSANDRA-18987

      This was found while testing Accord transactions with henrik.ingo and team.

      Attachments

        Issue Links

          Activity

            People

              maedhroz Caleb Rackliffe
              antithesis-luis Luis E Fernandez
              Caleb Rackliffe
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: