本项目完整地址 simple-redis
Redis 不支持原子事务,在 multi 排队执行时,如果在入队时发生错误则放弃执行,如果在 exec 执行时错误则跳过这条命令。
Simple-Redis 支持原子事务,在 multi 排队执行时,如果在入队时发生错误则放弃执行,在 exec 执行时错误则整条命令回滚。
原子事务
watch
在数据库存储引擎层,使用了并发的 dict 记录 key 和版本号的映射关系,当写命令执行成功时版本号加一。
在 Redis 中 watch 命令用于记录一个 key 当前的版本号,将版本号记录在客户端连接的上下文中。
事务
原子事务的实现是在数据库引擎层实现的,在 multi 后客户端发出的每一条命令,数据库只会检查语法错误并将命令记录在客户端连接的上下文中。
在 exec 时,才会从客户端连接的上下文中读取所有需要执行的命令队列。exec 命令的实现方式如下:
- 首先加写锁、加读锁(watch 的 key 也会加上读锁)。
- 检查 watch 的 key 版本是否变化,如果变化则直接返回,什么都不做。
- 依次执行每一条命令,如果开启了原子事务,则会记录 undo log。
- 如果执行成功,对相应的 key 增加版本号;如果执行失败,则根据 undo log 进行回滚。