Redis通过MULTI、EXEC、WATCH等命令来实现事务(transaction)功能。
事务阶段
一个事务会经历三个阶段:事务开始、命令入队、事务执行
事务开始
MULTI将客户端从非事务状态切换到事务状态,通过将客户端的Flags属性REDIS_MULTI打开实现的。
命令入队
每个客户端都有自己的事务状态,保存在RedisClient对象的mstate中
事务执行
当一个处于事务的客户端执行EXEC的时候,服务端会遍历客户端的事务队列,遍历执行,然后把结果返回给客户端。
Watch命令的实现
Watch是一个乐观锁,当一个键被监视之后,就会放入watched_keys字典中,字典的键是watch的键,值是监视的客户端。
当有数据库进行修改的命令时,会通过touchWatchKey函数将被修改的客户端的REDIS_DIRTY_CAS标识打开,标识客户端的安全性已经破坏。
当执行EXEC的时候,判断是否是否安全,如下
事务的ACID
原子性
Redis事务不支持回滚机制,出现命令错误的时候(非命令入队错误),也会执行下面的操作,所以本质上来说并不具备隔离性
隔离性
Redis是以单线程方式执行的,所以具备天然的事务隔离。
一致性
一致性是指系统从一个正确的状态,迁移到另一个正确的状态
持久性
当服务器运行在AOF持久化模式下,并且appendfsync选项的值为always时,事务也具有耐久性。