MULTI
COMMAND1
COMMAND2
.
.
.
WATCH key1, key2, key3
EXEC
MULTI
COMMAND3
COMMAND4
.
.
.
EXEC
I would like the second transaction to fail on the WATCH, but not the first.
> MULTI
> COMMAND1
> COMMAND2
> .
> .
> .
> WATCH key1, key2, key3
> EXEC
>
> MULTI
> COMMAND3
> COMMAND4
Hello, please can you tell us what is your goal instead of *how* you
want to accomplish it?
In general I think that what you want to do can be modeled with a
single MUTLI/EXEC/WATCH block but it's better to have a few more
details.
Thank you,
Salvatore
--
Salvatore 'antirez' Sanfilippo
http://invece.org
"We are what we repeatedly do. Excellence, therefore, is not an act,
but a habit." -- Aristotele
1) call transaction A, which calls GET K on a key K, returning value V1
2) compare V1 with some in-memory value, and decide whether to call
transaction B
3) transaction B calls SET K V2, with new value V2
4) fail transaction B if K has changed, because the decision in step 2
may no longer
be valid if K has changed
If I issue
WATCH K
after the first MULTI/EXEC, then it is possible that another
client will have changed K before the WATCH was issued,
so I will miss the change. So, I would like a guarantee that no other
commands get processed
before the WATCH gets issued. If I issued the WATCH at the very
beginning, then of course the first
transaction would reset the WATCH after it executed.
Note: I need to use transactions, because there are a few other
commands I need to call
along with the GET and SET.
> --
> You received this message because you are subscribed to the Google Groups "Redis DB" group.
> To post to this group, send email to redi...@googlegroups.com.
> To unsubscribe from this group, send email to redis-db+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
>
>
Can you GET K before your first MULTI? If so, can you combine the two transactions? After getting K you can decide which commands to use inside the MULTI. Either that or perform the WATCH inbetween the transactions, you can always call DISCARD if the value isn't what you want.
I've re-arranged my code so that I can get away with only a single MULTI/EXEC.
Problem solved :) I still think it could be useful to have EXEC pass in a flag
that disabled the post-transaction UNWATCH. Then it would be possible
to choose which transaction would fail on the WATCH. Or, alternatively
, if EXEC detected that a WATCH
was queued, then it could disable post-transaction UNWATCH.
On 2010-12-19 6:58 PM, "Aaron Boxer" <box...@gmail.com> wrote:
>
> Thanks, Derek.A WATCH between transactions could miss a change
> directly after the first
> transaction but before the WATCH gets called. And DISCARD wouldn't
> work because I wouldn't
> know that I needed to call it.
I don't know enough about your code, but I meant something like this after the first transaction:
- WATCH K
- GET K
- decide if 2nd transaction should run based on previous value from first transaction, or else DISCARD.
Doing it in one transaction is probably best though.
>
> I've re-arranged my code so that I can get away with only a single MULTI/EXEC.
> Problem solved :) I still think it could be useful to have EXEC pass in a flag
> that disabled the post-transaction UNWATCH. Then it would be possible
> to choose which transaction would fail on the WATCH. Or, alternatively
> , if EXEC detected that a WATCH
> was queued, then it could disable post-transaction UNWATCH.
>
Isn't checking manually as above just about as useful?
Here is my original check and set:
MULTI
GET K
other stuff
EXEC
Decide if I am going to SET K with a new value, based on the value I
received with GET.
If so, then:
MULTI
SET K NEW_VALUE
other stuff
EXEC
otherwise
UNWATCH
I need to be assured that once I GET K, that K will not change until after SET.
So, where can I put the WATCH?
If I put it before the first transaction, then the
first transaction will UNWATCH when it executes.
If I put it after the first transaction, the key K may have changed,
but I wouldn't
know about it.
That's why it would be nice be able to call
EXEC NO_UNWATCH
for the first transaction.
WATCH K
GET K
compare to K that was received above, if it is different or if you
don't want to SET K, UNWATCH, or else carry on:
MULTI
SET K NEW_VALUE
other stuff
EXEC
I would think this would be okay since the first transaction is
already done and can no longer fail. if you were able to use one WATCH
for both then the first transaction would still be completed even if
the second failed due to a changing of K. If the first transaction
should fail if the second one does, then they probably should be done
as one. It isn't too important though as this is probably slower then
doing it with a single transaction, which I assume you did something
like this:
WATCH K
GET K
decide what commands to use for multi depending on K
MULTI
do stuff
possibly SET K
EXEC
--
Derek
Thanks! Will add that to my bag of tricks.
In general you know there is something strange in your code if you
have a GET or other read operation inside a transaction.
The whole point of WATCH is the following pattern:
WATCH key
... some read operation against key ...
... possibly a conditional ...
MULTI
... write stuff ...
EXEC
Cheers,
Salvatore
--
Hello, I can assure you it is never useful to call WATCH inside MULTI.
Actually it does not make any sense at all because of the semantics of
Redis transactions.
Salvatore
--
Salvatore 'antirez' Sanfilippo
open source developer - VMware
--
Ingvar, everything executed inside a MULTI/EXEC block is executed atomically, so any key you watch after the MULTI cannot change before the EXEC.