Lightweight Transactions (Compare-and-set) — Cassandra Driver 3.13.0 documentation (original) (raw)
Lightweight Transactions (LWTs) are mostly pass-through CQL for the driver. However, the server returns some specialized results indicating the outcome and optional state preceding the transaction.
For pertinent execution parameters, see Statement.serial_consistency_level.
This section discusses working with specialized result sets returned by the server for LWTs, and how to work with them using the driver.
Specialized Results¶
The result returned from a LWT request is always a single row result. It will always have prepended a special column named [applied]
. How this value appears in your results depends on the row factory in use. See below for examples.
The value of this [applied]
column is boolean value indicating whether or not the transaction was applied. If True
, it is the only column in the result. If False
, the additional columns depend on the LWT operation being executed:
- When using a
UPDATE ... IF "col" = ...
clause, the result will contain the[applied]
column, plus the existing columns and values for any columns in theIF
clause (and thus the value that caused the transaction to fail). - When using
INSERT ... IF NOT EXISTS
, the result will contain the[applied]
column, plus all columns and values of the existing row that rejected the transaction. UPDATE .. IF EXISTS
never has additional columns, regardless of[applied]
status.
How the [applied]
column manifests depends on the row factory in use. Considering the following (initially empty) table:
CREATE TABLE test.t ( k int PRIMARY KEY, v int, x int )
… the following sections show the expected result for a number of example statements, using the three base row factories.
named_tuple_factory (default)¶
The name [applied]
is not a valid Python identifier, so the square brackets are actually removed from the attribute for the resulting namedtuple
. The row always has a boolean column applied
in position 0:
session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS") Row(applied=True)
session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS") Row(applied=False, k=0, v=0, x=None)
session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0") Row(applied=True)
session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0 AND x = 1") Row(applied=False, v=1, x=2)
tuple_factory¶
This return type does not refer to names, but the boolean value applied
is always present in position 0:
session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS") (True,)
session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS") (False, 0, 0, None)
session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0") (True,)
session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0 AND x = 1") (False, 1, 2)
dict_factory¶
The retuned dict
contains the [applied]
key:
session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS") {u'[applied]': True}
session.execute("INSERT INTO t (k,v) VALUES (0,0) IF NOT EXISTS") {u'x': 2, u'[applied]': False, u'v': 1}
session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0") {u'x': None, u'[applied]': False, u'k': 0, u'v': 0}
session.execute("UPDATE t SET v = 1, x = 2 WHERE k = 0 IF v =0 AND x = 1") {u'[applied]': True}