Redis事务
Redis事务
数据库ACID,redis实现方式
原子性
开启redis事务,使用multi+exec命令。中间的操作命令会存入FIFO队列,exec命令会依次执行这些命令。通过watch命令可以监控某个key是否被修改,如果某个key被修改,则监控这个key的客户端REDIS_DIRTY_CAS标识会被打开。而当这个客户端使用exec提交事务时,首先会校验REDIS_DIRTY_CAS标识是否被打开,如果被打开则当前事务不会提交,否则提交。
WATCH 命令是一个乐观锁(optimistic locking),它可以在 EXEC 命令执行之前,监视任意数量的数据库键,并在 EXEC 命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复。
每个 Redis 数据都保存着一个 watched_keys 字典,字典的键就是被 WATCH 命令监视的数据库键,而字典的值则是一个链表,链表中记录了所有监视相应数据库键的客户端
取消数据库键的监视
- WATCH 命令可以被调用多次。对键的监视从 WATCH 命令执行之后开始生效,直到调用 EXEC 命令为止,不管事务是否成功执行,对所有键的监视都会被取消。
- 当客户端断开连接时,该客户端对键的监视也会被取消。
- UNWATCH 命令可以手动取消对所有键的监视。
验证:
- 首先开启一个客户端A,使用watch命令监控key a,之后开启事务,依次将set命令加入事务队列中:
- 此时不提交事务,而是新开一个客户端B,对客户端A监控的key a进行set操作,成功返回ok:
- 此时切换到客户端A,使用exec提交事务,将会返回nil,拒绝事务提交。如此上午watch机制得到验证。
一致性
“一致”指的是数据符合数据库本身的定义和要求,没有包含非法或者无效的错误数据。
入队错误
- 可以通过检查命令是否合法,拒绝事务执行
执行错误
- 执行过程中,错误命令前的不会受影响,正常执行,对内存中的操作也不会收到影响
redis宕机
- redis可以通过AOF或RDB恢复数据
隔离性
- redis天生为单线程,事务总是以串行的方式运行的,并且事务也总是具有隔离性的。
持久性
- 当服务器运行在 AOF 持久化模式下,并且
appendfsync
选项的值为always
时,程序总会在执行命令之后调用同步(sync)函数,将命令数据真正保存到硬盘里,因此这种配置下的事务是具有持久性的。