Redis 事务

redis支持事务(A->原子性 C->一致性 I->隔离性 D->持久性)中的A 和 I

1.在一个Redis事务中,Redis要么执行其中的所有命令,要么什么都不执行。因此,Redis事务能够保证原子性。

2.Redis会将一个事务中的所有命令序列化,然后按顺序执行。Redis不可能在一个Redis事务的执行过程中插入执行另一个客户端发出的请求。这样便能保证Redis将这些命令作为一个单独的隔离操作执行。

我们正常的观念认为,当执行某一个事务中,有报错就会回滚数据,redis并不是这样处理的。

首先明确阐述,redis是没有回滚的。然后我们探讨一直性的问题,如下:

redis一直性的处理方式是,如果语法上明确的出现ERROR,会认为整个事务就是ERROR,但数据上出现ERROR,其余命令还是会成功。

以下是语法出错,这个事务也就是错误的,可无休止的键入命令,但都不会成功。


以下是,数据错误,有重复的 key 出现,但并不影响其余命令的操作。


redis事务网络中断或者服务停止宕机的修复方式

当某个客户端正在执行一次事务时,如果它在调用MULTI命令之前就从Redis服务端断开连接,那么就不会执行事务中的任何操作;相反,如果它在调用EXEC命令之后才从Redis服务端断开连接,那么就会执行事务中的所有操作。当Redis使用只增文件(AOF:Append-only File)时,Redis能够确保使用一个单独的write(2)系统调用,这样便能将事务写入磁盘。

如果Redis服务器宕机,或者系统管理员以某种方式停止Redis服务进程的运行,那么Redis很有可能只执行了事务中的一部分操作。Redis将会在重新启动时检查上述状态,然后退出运行,并且输出报错信息。

使用redis-check-aof工具可以修复上述的只增文件,这个工具将会从上述文件中删除执行不完全的事务,这样Redis服务器才能再次启动。

redis事务相关命令

MULTI -> 用于标记事务块的开始。Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令原子化地执行这个命令序列。这个命令的返回值是一个简单的字符串,总是OK。

EXEC -> 在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。当使用WATCH命令时,只有当受监控的键没有被修改时,EXEC命令才会执行事务中的命令,这种方式利用了检查再设置(CAS)的机制。这个命令的返回值是一个数组,其中的每个元素分别是原子化事务中的每个命令的返回值。 当使用WATCH命令时,如果事务执行中止,那么EXEC命令就会返回一个Null值。

DISCARD -> 清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态。如果使用了WATCH命令,那么DISCARD命令就会将当前连接监控的所有键取消监控。这个命令的返回值是一个简单的字符串,总是OK。


WATCH -> 当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的。这个命令的返回值是一个简单的字符串,总是OK。对于每个键来说,时间复杂度总是O(1)。

以下演示了 watch乐观锁 的示例,(1)当一个客户端(A)对一个变量(a)进行了监听此时a = 3并开启了事务,另一个客户端(B)改变了a的值 a = 4,那么(A)客户端执行完事务后,exec会返回 nil (null) ,(2)如果没有竞争,则正确执行。




watch 一定是和事务一起使用才有效。

UNWATCH -> 清除所有先前为一个事务监控的键。如果你调用了EXEC或DISCARD命令,那么就不需要手动调用UNWATCH命令。这个命令的返回值是一个简单的字符串,总是OK。

非事务型流水线pipeline

其实使用事务底层用了(pipeline),可以将我们在事务里的命令一次性发送来减少通信次数并降低延迟,有些需要执行大量的命令情况下,也会使用事务来执行,但是事务并不是免费的,它们会消耗资源,并且可能导致其他重要的命令被延迟执行。不过好消息是 我们自己可以通过使用 pipeline() 来直接执行我们的大量命令。

你可能感兴趣的:(Redis 事务)