Redis事务实现原理

316 阅读2分钟

事务

pipeline和串行化模式在多个客户端存在的情况下,不同客户端的命令可能会交替执行。

这样情况下,一个客户端无法实现批量执行的命令原子化执行,因此需要redis事务实现原子化。

概念:客户端一次事务希望命令可以原子化执行,没有其他命令掺入。

实现:客户端开启事务命令后,发送的命令暂存在服务端的队列中,当所有命令发送完成后,再批量执行。由于redis单线程执行命令,因此可以确保不会执行其他客户端的命令。

事务中读写命令的区分及造成的问题:

客户端应该在入队列时确定每个写命令的值,即不能依赖其他命令执行结果。而事务操作需要只读操作判断写入的值。但是队列中要批量执行的只有写入操作,因为批量执行只读操作没有意义。需要客户端先执行读取命令,判断要写入的值,再加事务去执行。但这之间存在其他客户端更改之前读过的记录的可能。

redis实现乐观锁解决这一问题:

1、将事务涉及的key加入观察者模式watch

2、执行只读操作

3、客户端根据只读操作,设置写操作的值

4、发送写命令入队列

5、批量提交。此时如果之前被watch的key被修改,则exec失败,拒绝执行。

注:

redis事务无法实现严格一致性:当事务中的命令开始exec执行时,若执行出现错误,后续命令继续执行,只会在返回时标记出错的命令和结果,由客户端决定如何恢复。redis自身并不支持回滚,因此无需引入版本机制。