首页 Redis事务
文章
取消

Redis事务

Redis事务和MySQL事务对比(主要是操作流程)

MySQL:

  1. 开启事务
  2. 执行事务
  3. 提交(正常执行)/(出现异常)回滚事务

Redis:

  1. 开启事务
  2. 任务入队列(一个先进先出的结构,命令的执行顺序是先进先执行)
  3. exec/discard事务

机制:事务开启后,每次输入的指令会依次入事务队列,待执行exec执行后,队列中的命令会按照进入顺序,依次执行

命令介绍

  1. multi:开启事务,事务执行之后不能嵌套执行
  2. exec:执行事务
  3. discard:放弃整个事务
  4. expire:设定过期值(值只能为数字,如 expire key 10,而expire key 10s是错误的)
  5. watch:用于在客户端并发中,为事务提供一个乐观锁(也就是CAS,及Check And Set),也就是在执行了watch命令并监控了某几个变量,如果变量被并发事务更改,事务就会发生回滚
  6. unwatch:是否所有变量的乐观锁(在)

事务错误和回滚

  1. 执行时错误(不回滚),如对于命令expire k 10s,本身没有缺少参数,但是参数的类型是错误的,因此在执行的时候会报错
  2. 指令入队列时错误,并且会终止整个事务(回滚),如对于指令set k,因为缺少参数,会在入队列时发生错误,并且会终止整个事务(事务开启后的指令都不会执行)
  3. 指令入队列时错误,不会终止整个事务(不回滚),如:在开启事务后,输入指令multi,在事务中嵌套开启事务,不能入队列,发生错误,但是不会影响事务的执行

Redis为什么不支持运行时错误事务回滚

  1. 作者认为错误通常是编译错误造成的,这些错误通常在开发环境中出现,极少出现在生产环境中
  2. 与Redis追求简单高效的设计原则不符

watch指令种的事务回滚

  1. watch执行的时机:在事务开启之前执行
  2. 即使把原对象的值重新赋值给原对象,watch依然生效
  3. 在事务中执行watch命令会报错,但不会终止事务

预留问题

是否在队列中如果有指令unwatch的存在,watch就没有用了

总结

事务回滚的情况

  1. watch监控的变量在事务执行期间被修改
  2. 指令缺少参数时入队列
本文由作者按照 CC BY 4.0 进行授权