incubator-cassandra-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Lebresne <sylv...@datastax.com>
Subject Re: Update multiple rows in a CQL lightweight transaction
Date Tue, 25 Feb 2014 10:54:06 GMT
On Mon, Feb 24, 2014 at 11:32 PM, Tupshin Harper <tupshin@tupshin.com>wrote:

> Hi Clint,
>
> That does appear to be an omission in CQL3. It would be possible to
> simulate it by doing
> BEGIN BATCH
>     UPDATE foo SET z = 10 WHERE x = 'a' AND y = 1 IF t= 2 AND z=10;
>     UPDATE foo SET t = 5,z=6 where x = 'a' AND y = 4
> APPLY BATCH;
>
> However, this does a redundant write to the first row if the condition
> holds, and I certainly wouldn't recommend doing that routinely.
>

I'm not sure what would be the big deal of redundantly writing the first
row to it's existing value really. Performance wise, it's going to be
rather negligible since if you use a condition you are, by extension,
updating rows in the same partition, and so all of it ends up in the same
internal Mutation and there is very very little cost to adding one more
column to that mutation. The only minor downside is that it would bump the
writeTime() value for that column, but I can't imagine all that many
application for which that would be a big deal (though I suppose it could
be possible to support UPDATE with an empty SET clause so that you can put
condition on a row without updating it).

--
Sylvain



>
> Alternatively, depending on your needs, you might be able to use a static
> column (coming with 2.0.6) as your conditional flag, as that column is
> shared by all rows in the partition.
>
> -Tupshin
>
>
>
> On Mon, Feb 24, 2014 at 3:57 PM, Clint Kelly <clint.kelly@gmail.com>wrote:
>
>> Hi Tupshin,
>>
>> Thanks for your help; I appreciate it.
>>
>> Could I do something like the following?
>>
>> Given the same table you started with:
>>
>> x | y | t | z
>> ---+---+---+----
>>  a | 1 | 2 | 10
>>  a | 2 | 2 | 20
>>
>> I'd like to write a compare-and-set that does something like:
>>
>> "If there is a row with (x,y,t,z) = (a,1,2,10), then update/insert a
>> row with (x,y,t,z) = (a,3,4,5) and update/insert a row with (x,y,t,z)
>> = (a,4,5,6)."
>>
>>
>> I don't see how I could do this with what you outlined above---just
>> curious.  It seems like what I describe above under the hood would be
>> a compare-and-(batch)-set on a single wide row, so it maybe is
>> possible with the Thrift API (I have to check).
>>
>> Thanks again!
>>
>> Best regards,
>> Clint
>>
>> On Sat, Feb 22, 2014 at 11:38 AM, Tupshin Harper <tupshin@tupshin.com>
>> wrote:
>> > #5633 was actually closed  because the static columns feature
>> > (https://issues.apache.org/jira/browse/CASSANDRA-6561) which has been
>> > checked in to the 2.0 branch but is not yet part of a release (it will
>> be in
>> > 2.0.6).
>> >
>> > That feature will let you update multiple rows within a single
>> partition by
>> > doing a CAS write based on a static column shared by all rows within the
>> > partition.
>> >
>> > Example extracted from the ticket:
>> > CREATE TABLE foo (
>> >     x text,
>> >     y bigint,
>> >     t bigint static,
>> >     z bigint,
>> > PRIMARY KEY (x, y) );
>> >
>> > insert into foo (x,y,t, z) values ('a', 1, 1, 10);
>> > insert into foo (x,y,t, z) values ('a', 2, 2, 20);
>> >
>> > select * from foo;
>> >
>> > x | y | t | z
>> > ---+---+---+----
>> >  a | 1 | 2 | 10
>> >  a | 2 | 2 | 20
>> > (Note that both values of "t" are 2 because it is static)
>> >
>> >
>> >  begin batch update foo set z = 1 where x = 'a' and y = 1; update foo
>> set z
>> > = 2 where x = 'a' and y = 2 if t = 4; apply batch;
>> >
>> >  [applied] | x | y    | t
>> > -----------+---+------+---
>> >      False | a | null | 2
>> >
>> > (Both updates failed to apply because there was an unmet conditional on
>> one
>> > of them)
>> >
>> > select * from foo;
>> >
>> >  x | y | t | z
>> > ---+---+---+----
>> >  a | 1 | 2 | 10
>> >  a | 2 | 2 | 20
>> >
>> >
>> > begin batch update foo set z = 1 where x = 'a' and y = 1; update foo
>> set z =
>> > 2 where x = 'a' and y = 2 if t = 2; apply batch;
>> >
>> >  [applied]
>> > -----------
>> >       True
>> >
>> > (both updates succeeded because the check on t succeeded)
>> >
>> > select * from foo;
>> > x | y | t | z
>> > ---+---+---+---
>> >  a | 1 | 2 | 1
>> >  a | 2 | 2 | 2
>> >
>> > Hope this helps.
>> >
>> > -Tupshin
>> >
>> >
>> >
>> > On Fri, Feb 21, 2014 at 6:05 PM, DuyHai Doan <doanduyhai@gmail.com>
>> wrote:
>> >>
>> >> Hello Clint
>> >>
>> >>  The Resolution status of the JIRA is set to "Later", probably the
>> >> implementation is not done yet. The JIRA was opened to discuss about
>> impl
>> >> strategy but nothing has been coded so far I guess.
>> >>
>> >>
>> >>
>> >> On Sat, Feb 22, 2014 at 12:02 AM, Clint Kelly <clint.kelly@gmail.com>
>> >> wrote:
>> >>>
>> >>> Folks,
>> >>>
>> >>> Does anyone know how I can modify multiple rows at once in a
>> >>> lightweight transaction in CQL3?
>> >>>
>> >>> I saw the following ticket:
>> >>>
>> >>>     https://issues.apache.org/jira/browse/CASSANDRA-5633
>> >>>
>> >>> but it was not obvious to me from the comments how (or whether) this
>> >>> got resolved.  I also couldn't find anything in the DataStax
>> >>> documentation about how to perform these operations.
>> >>>
>> >>> I'm in particular interested in how to perform a compare-and-set
>> >>> operation that modifies multiple rows (with the same partition key)
>> >>> using the DataStax Java driver.
>> >>>
>> >>> Thanks!
>> >>>
>> >>> Best regards,
>> >>> Clint
>> >>
>> >>
>> >
>>
>
>

Mime
View raw message