1

In redis, I have a hash where I want to first get and then set a value. I reckon I can use pipelining to speed up the whole operation via downsizing the round trips, like so:

my_pipeline = redis.Redis(connection_pool=POOL).pipeline()
my_pipeline.hget("my_hash","my_time")
my_pipeline.hset("my_hash","my_time",latest_time)
result = my_pipeline.execute()
old_value_of_my_time = result[0]

Essentially I've tried to retrieve the original value of my_time for later use, and then set a new value.

So the question is: is doing hget and hset on the same value in the same pipeline correct? I understand from this SO post (and general knowledge of pipelines) that the order of commands is preserved in pipelines. So ostensibly, my approach should be correct.

However I might be missing something, so can an expert vet this approach?

Note: I've used python syntax in the example code. Moreover, if I wasn't using a hash, I'd simply use getset for this operation. But note that I must use a hash in this case - for reasons outside the scope of this question.

Hassan Baig
  • 15,055
  • 27
  • 102
  • 205

1 Answers1

1

Yes, you can do HGET and HSET in the pipeline. However, it behaves slightly different from GETSET. GETSET is an atomic operation, but the combination of HGET and HSET in a pipeline is NOT atomic.

Redis guarantees that it runs your HGET command before your HSET command. However, Redis DOES NOT run these two commands atomically. So when it runs your HSET command, the HASH might already be modified by another client. In this case, you do not get the old value, but some older value.

In order to achieve something similar to GETSET, you have run HGET and HSET in a transaction, or wrap these two commands in a Lua script.

for_stack
  • 21,012
  • 4
  • 35
  • 48
  • Does redis support atomic transactions natively? – Hassan Baig Mar 21 '18 at 15:15
  • Of course. You can achieve that with [transaction related commands](https://redis.io/topics/transactions) or [Lua scripting](https://redis.io/commands/eval). – for_stack Mar 21 '18 at 16:28
  • out of scope for the question but I thought I'd put it forth. Do you speak python? I ask because in the docs (here: http://redis-py.readthedocs.io/en/latest/) for the python wrapper, it seems `pipeline` is implemented with `transaction=True` by default? I just want to confirm. – Hassan Baig Mar 21 '18 at 18:38