一提到事务,首先想到的是数据库的事务机制ACID, 原子性(Atomicity),一致性(Consistency),隔离性(Isolation)和持久性(Durability)

 

Redis事务特性

Redis 事务具有两个重要特性:

1) 单独的隔离操作

事务中的所有命令都会被序列化,它们将按照顺序执行,并且在执行过的程中,不会被其他客户端发送来的命令打断。

2) 不保证原子性

在 Redis 的事务中,如果存在命令执行失败的情况,那么其他命令依然会被执行,不支持事务回滚机制。

注意:Redis 不支持事务回滚,原因在于 Redis 是一款基于内存的存储系统,其内部结构比较简单,若支持回滚机制,则让其变得冗余,并且损耗性能,这与 Redis 简单、快速的理念不相符合。

 

 Redis 事务是方便用户一次执行多个命令。执行 Redis 事务可分为三个阶段:

  • 开始事务 (multi)
  • 命令入队
  • 执行事务 (exec)
  • 或取消事务 (discard)

不保证原子性例子

 命令执行失败:包括语法错误(编译时)和逻辑错误(运行时),语法错误时,都不执行;逻辑错误时,其余执行,仅不执行逻辑错误的命令.

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aa 1
QUEUED
127.0.0.1:6379> seett bb 1 #语法错误,没有此命令
(error) ERR unknown command `seett`, with args beginning with: `bb`, `1`,
127.0.0.1:6379> set cc 1
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
# 事务所有指令不能执行

 

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aa aa
QUEUED
127.0.0.1:6379> incr aa #逻辑错误,字符串不能自加
QUEUED
127.0.0.1:6379> set bb bb
QUEUED
127.0.0.1:6379> get bb
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
4) "bb"
# 事务命令 仅逻辑错误的没执行,其余都执行了

 

redis监视器

 锁机制

悲观锁:很悲观,认为什么时候都会出问题,无论做什么都加锁(效率低).

乐观锁:很乐观,认为什么时候都不会出问题,所以不会上锁(更新数据时判断一下,再次期间是否数据有改动)

  mysql,在数据表中加version字段,更新数据先,读取version,当更新数据时,比对version字段有没有被改动过,有改动就放弃更新,没改动则连同version一块更新.

 

redis有个监视器 WATCH 可以实现乐观锁,

spring事务redis回滚 redis事务支持回滚吗_Redis

 

 

E:\java\Redis-x64-5.0.9>redis-cli
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money out
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>

 

# 在上面步骤,开启事务后 但没有执行时运行.
E:\java\Redis-x64-5.0.9>redis-cli
127.0.0.1:6379> decrby money 20
(integer) 80
127.0.0.1:6379>

 

 

事务如果执行成功,监视器会自动取消。

如果像上面事务未成功,首先unwatach,取消监视,重新watch,循环上面的业务.