redis-transaction

redis-transaction

注意

  1. 不支持回滚操作是因为redis是先执行指令然后做日志,所以即使发生异常,没有可以用来执行回滚操作的日志。
  2. 只保证事物的隔离性, 不保证原子性.
  3. redis 禁止在 multiexec 之间执行 watch 指令,而必须在 multi 之前做好盯住关键变量,否则会出错。

事物的过程

multi:

事物的开始(创建一个事物);

exec:

事物的执行;

discard:

丢弃这个事物;

127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 2
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> incr books
QUEUED
127.0.0.1:6379> exec
1) (integer) 3
2) (integer) 4
3) (integer) 5

原理

redis 单线程且本身保证有序,且能保证不被其他指令打扰.–仅仅是保证了隔离性
redis multi和exec命令不能保证原子性,中间执行的多个命令有一个失败了,不会影响其他命令的执行.
redis multi和exec仅仅保证一堆命令不被插队,顺序执行.原理是在server端开启了一个事物队列.

优化

建议使用pipeline 提升性能.

pipe = redis.pipeline(transaction=true)
pipe.multi()
pipe.incr("books")
pipe.incr("books")
values = pipe.execute()

避免并发问题

悲观锁: 分布式锁
乐观锁: watch机制

watch机制

> watch books
OK
> incr books  # 被修改了
(integer) 1
> multi
OK
> incr books
QUEUED
> exec  # 事务执行失败
(nil)

watch 会实时检查观察的key是否被改变,如果改变了exec提交会执行失败,返回null.

    原文作者:宁振航丶
    原文地址: https://www.jianshu.com/p/16e095379c68
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞