Two Round Trips Too Many

Three ways to release a Redis lock held under SET lock:invoice:88 <my_token> NX PX 30000.

# release_a
r.delete("lock:invoice:88")

# release_b
if r.get("lock:invoice:88") == my_token:
    r.delete("lock:invoice:88")

# release_c
RELEASE = """
if redis.call("get", KEYS[1]) == ARGV[1] then
  return redis.call("del", KEYS[1])
else
  return 0
end
"""
r.eval(RELEASE, 1, "lock:invoice:88", my_token)

release_a is clearly unsafe. What is still wrong with release_b?

A

release_b needs a WATCH on the key before the get so the client is notified if it changes.

B

The check and the delete are two separate round trips, so the lease can expire and another client can acquire between them, and the delete then removes that client's lock.

C

Nothing is wrong. release_b and release_c are equivalent, and the script is only preferable because it saves a round trip.

D

r.get returns bytes while my_token is a string, so the comparison never succeeds and the lock is left to expire on its own.