I need to atomically insert multiple rows in a Cassandra table that have different partition keys. At the same time, I need to make sure for each query that the state of data user is updating/inserting is correct (so that in case of race condition the data doesn't get messed up).
For example, the db structure is:
create table test(
id uuid,
userid uuid,
address text,
PRIMARY KEY ((id), userid)
);
When inserting rows, I need to make sure for each of them that this PK doesn't exist in the database, I don't want to accidentally overwrite data (Cassandra would just do that). For that purpose, lightweight transactions exist, so I can just add IF NOT EXISTS clause and it will be done. But the problem is that I have several such inserts that should either all succeed or none of them.
The following solution doesn't work:
BEGIN BATCH
INSERT INTO test(id, userid, address) VALUES(50fcdfd9-7f61-11e5-9c9d-a0999b0af139, daf38231-eab1-4cd3-ae31-8d28d15c762b, 'addr1') IF NOT EXISTS;
INSERT INTO test(id, userid, address) VALUES(9c26fcc0-0f82-472c-8e83-01b90bed60cc, 0d1a91c4-780a-4bc6-9c12-f2976cb7b3ef, 'addr2') IF NOT EXISTS;
APPLY BATCH;
The emitted error is: Batch with conditions cannot span multiple partitions. Documentation says just that without offering a workaround. Is there a way to enforce atomicity and consistency of that kind on the database layer? I understand that ACID principle cannot be guaranteed for Cassandra, but I can't find an answer to why is that restriction for batch statements classified as an error rather than a warning? What can serve as a workaround for this problem?
Any ideas and help with understanding Cassandra philosophy would be appreciated