Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent race conditions using Redis?

I used Only Redis as my DB, and my client is ServiceStack.Redis. The thing is, if two concurrent request need to update one key, then it can be a race condition. For example

A:

  1. int a = Get key
  2. MULTI
  3. a = a - 100
  4. Set key a
  5. EXEC

B:

  1. int a = Get key
  2. MULTI
  3. a = a - 100
  4. Set key a
  5. EXEC

if the origin "key" is 1000. If speration A and B are serialized, the right results of this two operations of "key" will be 800. But if A and B happens in the same time. Before A can commit, Operation B get value 1000 from "key", and set 900 to "key". That's not what I want. How can I prevent this kind of race conditions, use "WATCH"?

like image 901
Allan Yang Avatar asked Feb 14 '15 08:02

Allan Yang


People also ask

How does Redis prevent race conditions?

Fortunately, Redis has another data structure that we can use to prevent these race conditions – the sorted set. Here's the algorithm we came up with: Each user has a sorted set associated with them. The keys and values are identical, and equal to the (microsecond) times when actions were attempted.

How can race conditions be prevented?

To avoid race conditions, any operation on a shared resource – that is, on a resource that can be shared between threads – must be executed atomically. One way to achieve atomicity is by using critical sections — mutually exclusive parts of the program.

How do you handle race condition in multithreading?

an easy way to fix "check and act" race conditions is to synchronized keyword and enforce locking which will make this operation atomic and guarantees that block or method will only be executed by one thread and result of the operation will be visible to all threads once synchronized blocks completed or thread exited ...

How do you avoid race condition in Unix?

(1) Move the lock file outside the main loop, so that two instances of your program cannot run their main loop at the same time. If one is running, the other will have to wait until it's done, then start replacing the output file. (2) Make the two instances cooperate, by examining what the contents of the file are.


1 Answers

You should read the docs on Transactions in Redis, transactions in Redis is essentially batching multiple operations so they're executed as a single atomic operation.

Since it's only batching operations, you cannot perform any reads within the context of a transaction. Any reads you need before hand need to be retrieved before the start of the transaction. You can then use the Redis WATCH to watch for any keys that shouldn't be modified before your transaction completes, if a key was modified the transaction will fail and no operations will be processed.

like image 189
mythz Avatar answered Sep 21 '22 04:09

mythz