最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

concurrency - is Redis wrong about its transactions being atomic? - Stack Overflow

programmeradmin1浏览0评论

Redis' definition on atomicity taken from its docs on ACID transactions /

If any part of the transaction fails, the entire transaction must be rolled back, meaning that any changes made during the transaction are undone.


It seems to me that the documentation is mixing up the term atomicity and isolation. Take look this snippet from Redis' transaction docs: :

The following example increments keys foo and bar atomically.

> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1

If INCR bar fails during execution for whatever reason, INCR foo will still be reflected as there is no transaction rollback. This is, by Redis' own definition of atomicity, is not atomic.

The whole documentation page on transactions, seems to me, is using the term atomicity where isolation is the more correct term.

What am I missing?

Redis' definition on atomicity taken from its docs on ACID transactions https://redis.io/glossary/acid-transactions/

If any part of the transaction fails, the entire transaction must be rolled back, meaning that any changes made during the transaction are undone.


It seems to me that the documentation is mixing up the term atomicity and isolation. Take look this snippet from Redis' transaction docs: https://redis.io/docs/latest/develop/interact/transactions/#usage:

The following example increments keys foo and bar atomically.

> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1

If INCR bar fails during execution for whatever reason, INCR foo will still be reflected as there is no transaction rollback. This is, by Redis' own definition of atomicity, is not atomic.

The whole documentation page on transactions, seems to me, is using the term atomicity where isolation is the more correct term.

What am I missing?

Share Improve this question asked Mar 13 at 10:19 Leonardus ChenLeonardus Chen 1,2749 silver badges20 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

As documented here, transactions in Redis ensure:

  1. Other clients won’t see a partial state, meaning that all clients will see the state either before the transaction was applied, or after.

  2. In case of a node failure, once Redis restarts, it will reload either the whole transaction or none of it from the AOF file.

The first is about isolation. The second is about atomicity.

There can be two types of events during a transaction execution we need to analyze:

  • Some commands may return an error

  • An extreme event that breaks the execution - e.g., system crash, component failure, power outage.

Let's examine it more carefully.

Some commands may return an error

Redis transactions are atomic in that either every command in a transaction is processed (accepted as valid and queued for execution) or none are. When a transaction in Redis is executed, some commands may return errors. You may expect a transaction to rollback if one or more of the commands return an error, but this is not required to be considered atomic. Note the following paragraph:

Errors happening after EXEC instead are not handled in a special way: all the other commands will be executed even if some command fails during the transaction.

Also here:

Redis does not support rollbacks of transactions since supporting rollbacks would have a significant impact on the simplicity and performance of Redis.

An extreme event that breaks the execution

Extreme events can always happen, as a power supply, a network interface, a RAM, or a flash module may fail during a transaction execution. When recovering, we need to ensure that recovered data reflects the state before or after the transaction execution, but not a partial state. That is what atomicity is about, and that is exactly the second guarantee:

in case of a node failure, once Redis restarts, it will reload either the whole transaction or none of it from the AOF file.

However, the documentation here states:

Atomicity – indivisible and irreducible characteristics are achieved using Redis transaction commands (i.e. WATCH/MULTI/EXEC) or Lua scripting. “All or nothing” property is almost always achieved, excluding cases like OOM (Out Of Memory) or a buggy Lua script.

Redis is being careful here, stating that under extreme conditions that don't result in a crash, transactions may result in partial execution.


You are correct - there is indeed some mix between atomicity and isolation in the documentation. For example, here:

Redis has the ability to execute Lua scripts on the server side. Lua scripts are executed atomically, that is, no other script or command will run while a script is running, which gives us the same transactional semantics as MULTI / EXEC.

This is defently about isolation and not about atomicity.

Also, the quoted definition of atomicity: "If any part of the transaction fails, the entire transaction must be rolled back", is problematic, mostly because fails is not defined, and it is described in terms of possible implementation details (which is not how it is implemented in Redis), and not in terms of guarantees.

发布评论

评论列表(0)

  1. 暂无评论