>>But as you said that UNWATCH, can not cancel otslezhivnie particular key. But how can that be? If you cancel the tracking of all the keys, then perhaps there are problems, such as race, etc. >>(because of possible concurrent requests for tracking)
>>Tell me what to create one?
Okay ... my faith in automatic translation tools is getting lower and lower.
My understanding is you need to find and update a specific item in a list
in a concurrent environment (atomicity and isolation required).
You can do it almost as you describe:
WATCH mylist
LRANGE mylist 0 -1
Find item in the list -> index
MULTI
If item has been found:
LSET mylist index new_value
EXEC
else:
DISCARD
... and of course the client using these commands has to check the result
of EXEC and loop if needed.
Please note the DISCARD or UNWATCH commands apply to all keys ***for a given connection***.
In practice, you cannot handle several transactions on the same connection, so the DISCARD and
UNWATCH applies to the keys involved in the last transaction. If you need to run several transactions
in parallel, then you will need several connections as well.
Another solution is to rely on Redis 2.6 and a Lua script.
Here is an example in Python:
import redis
POOL = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=POOL)
SCRIPT = """
local n = redis.call('LLEN', KEYS[1]) - 1
for i=0,n do
local val = redis.call( 'LINDEX', KEYS[1], i )
if val == ARGV[1] then
redis.call( 'LSET',KEYS[1], i, ARGV[2] )
return i
end
end
return -1
"""
r.flushall()
r.rpush( "mylist", 1, 2, 3, 4, 5, 6 )
print r.lrange("mylist",0,-1)
print r.execute_command( "EVAL", SCRIPT, 1, "mylist", 4, 10 )
print r.lrange("mylist",0,-1)
print r.execute_command( "EVAL", SCRIPT, 1, "mylist", 20, 30 )
print r.lrange("mylist",0,-1)
Lua scripts being executed atomically, there is no need of WATCH/MULTI/EXEC
blocks here.
Regards,
Didier.