Redis事务

MULTI 、 EXEC 与 WATCH

当输入MULTI时,标志着事务的开始,之后命令入队,当输入EXEC时,表示开始执行事务。

WATCH命令是一个乐观锁(optimistic locking),它可以在EXEC命令执行之前,监视任意数量的数据库键,并在EXEC命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复。

WATCH功能的实现原理:每个Redis数据库都保存着一个watched_keys字典,这个字典的键是某个被WATCH命令监视的数据库键,而字典的值则是一个链表,链表中记录了所有监视相应数据库键的客户端。所有对数据库修改的命令,在执行完这些命令之后,Redis就会从字典中查看刚刚修改的键是否被其他客户端监视,如果是的话,那么就将该客户端的CAS标识打开,表明该客户端的事务安全性被破坏。因此当服务器收到了一个客户端发来的EXEC命令时,它会先判断该客户端的CAS标识是否被打开,如果被打开,那就拒绝执行,反之可以正常执行。

原子性

有三种情况:

1.正常情况下,MULTI开启事务之后,输入的命令正常入队,EXEC提交之后,所有命令正常执行。

2.事务因为某条命令入队出错而被拒绝执行。比如我们只输入了一个GET那么服务器就会拒绝执行本次事务。

3.所有命令成功入队,但是在执行时有一条命令执行出错,那么该条命令不执行,其他命令正常执行。比如:我们对一个String类型的键执行的List类型的操作,这对Redis语法来说是不允许的,所以说会执行出错。

从第三种情况来看,Redis是不支持回滚功能的。而第三种情况又是完全可以避免的,所以既可以说Redis是具有原子性的,也可以说Redis是不具有原子性的。

一致性

Redis事务是具有一致性的,这一点毋庸置疑的,下面看一下它是如何保证的。

1.如果一个事务在入队命令的过程中,出现了命令不存在,或者命令的格式不正确等情况,那么Redis将拒绝执行这个事务

2.因为在事务执行的过程中,出错的命令会被服务器识别出来,并进行相应的错误处理,所以这些出错命令不会对数据库做任何修改,也不会对事务的一致性产生任何影响。

3.如果服务器停机,Redis会通过RDB或者AOF这些持久化手段来恢复数据,那么数据总是保持一致的。

隔离性

因为Redis是在单线程下,也就是串行化的方式来执行任务的,所以它总是隔离的。

持久性

需要注意的是,Redis只有在AOF持久化模式下,并且每写入一条更新命令都被写入AOF文件时,才是具有持久性的。

关于Redis的持久化方式可以访问另外一篇文章:
https://blog.csdn.net/m0_52373742/article/details/122849768?spm=1001.2014.3001.5501
参考《Redis设计与实现》

你可能感兴趣的:(笔记,redis,事务)