X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/43f30ac0f9bcc4a7afb06136a8dfe5b703be7935..a89b7013ff5aa27fae4d1f7d45615349c3ab7300:/doc/SetnxCommand.html diff --git a/doc/SetnxCommand.html b/doc/SetnxCommand.html index ed4ee167..8c47e72d 100644 --- a/doc/SetnxCommand.html +++ b/doc/SetnxCommand.html @@ -16,7 +16,7 @@
-SetnxCommand: Contents
  SETNX _key_ _value_
    Return value +SetnxCommand: Contents
  SETNX _key_ _value_
    Return value
    Design pattern: Implementing locking with SETNX
      Handling deadlocks

SetnxCommand

@@ -31,8 +31,17 @@

Return value

Integer reply, specifically:

 1 if the key was set
 0 if the key was not set
-
- +

Design pattern: Implementing locking with SETNX

SETNX can also be seen as a locking primitive. For instance to acquirethe lock of the key foo, the client could try the following:
+
+SETNX lock.foo <current UNIX time + lock timeout + 1>
+
If SETNX returns 1 the client acquired the lock, setting the lock.fookey to the UNIX time at witch the lock should no longer be considered valid.The client will later use DEL lock.foo in order to release the lock.
+
If SETNX returns 0 the key is already locked by some other client. We caneither return to the caller if it's a non blocking lock, or enter aloop retrying to hold the lock until we succeed or some kind of timeoutexpires.
+

Handling deadlocks

In the above locking algorithm there is a problem: what happens if a clientfails, crashes, or is otherwise not able to release the lock?It's possible to detect this condition because the lock key contains aUNIX timestamp. If such a timestamp is <= the current Unix time the lockis no longer valid.
+
When this happens we can't just call DEL against the key to remove the lockand then try to issue a SETNX, as there is a race condition here, whenmultiple clients detected an expired lock and are trying to release it.
+ +
Fortunately it's possible to avoid this issue using the following algorithm.Let's see how C4, our sane client, uses the good algorithm:
+ +IMPORTANT NOTE: In order to make this locking algorithm more robust, a client holding a lock should always check the timeout didn't expired before to unlock the key with DEL because client failures can be complex, not just crashing but also blocking a lot of time against some operation and trying to issue DEL after a lot of time (when the LOCK is already hold by some other client).