Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StackExchange.Redis: couple of questions about transactions

I've got several question about using transactions from StackExchange.Redis:

  1. Is it allowed to execute commands in transaction which could potentially target different nodes in cluster environment? Say, first command's key has {1} hashtag and second command's key has {2} hashtag.
  2. When does transaction's Execute()/ExecuteAsync() returns false? Only when set conditions were not met? Could it return false if there were no conditions set?
  3. If some network or internal Redis error occur, will Execute()/ExecuteAsync() throw or just return false? Should I also check commands' tasks (assuming that commands are fully correct and normally are not expected to throw) or they will just be cancelled?

Unfortunately the doc doesn't explain #2 and #3 in details.

like image 896
andreycha Avatar asked Feb 09 '18 17:02

andreycha


People also ask

How many transactions can Redis handle?

Using a single AWS EC2 instance, Redis was able to achieve 1,200,000 transactions per second at <1 msec (sub millisecond) latency.

Does Redis support transaction?

Redis Transactions allow the execution of a group of commands in a single step, they are centered around the commands MULTI , EXEC , DISCARD and WATCH . Redis Transactions make two important guarantees: All the commands in a transaction are serialized and executed sequentially.

Are Redis transactions Atomic?

Redis transaction is also atomic. Atomic means either all of the commands or none are processed.

How are Redis pipelining and transaction different?

Unlike pipelines, pipelines use special commands to mark the beginning and the end of the transaction, and the server also can queue the commands from a transaction (so the client can send one at a time). So transactions are stateful on the server, it actually keeps track of an ongoing transaction.


1 Answers

I've digged a bit into StackExchange.Redis source code and played with the driver, here are my observations:

  • no actual interaction happens when you call op methods on ITransaction instance
  • driver starts talking to Redis only when you call Execute()/ExecuteAsync()

The answers seem to be the following:

  1. As @royi-mindel mentioned, all keys in transaction must target the same slot. Otherwise you get "Multi-key operations must involve a single slot" exception.
  2. Execute()/ExecuteAsync() returns false in two cases: when transaction was discarded because conditions were not met, and when driver failed to queue the command (for example because of server OOM). All command tasks will be marked as canceled. Also Execute()/ExecuteAsync() does not return false if one of the commands failed during execution (for example, because of wrong type operation).
  3. In case some network problem occurs, Execute()/ExecuteAsync() will throw an exception and all commands tasks will remain in "waiting for activation" state.

To sum it up, command tasks should only be checked if Execute()/ExecuteAsync() returned true: every task will either contain a result or an error (see Exception property).

like image 75
andreycha Avatar answered Sep 22 '22 16:09

andreycha