Redis 事务
Posted 周天祥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 事务相关的知识,希望对你有一定的参考价值。
Redis 事务
1、Redis 事务介绍
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
批量操作在发送 EXEC 命令前被放入队列缓存。
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
Redis事务的三个阶段:
开始事务。
命令入队。
执行事务。
Redis事务开始后, 会缓存后续的操作命令及其操作数据,当事务提交时,原子性的执行缓存的命令序列。
Redis提供了一种乐观的锁机制, 配合这种机制,Redis事务提交时, 变成了事务的条件执行。具体的说,如果乐观锁失败了,事务提交时, 丢弃事务中的命令序列,如果乐观锁成功了, 事务提交时,才会执行其命令序列。当然,也可以不使用乐观锁机制, 在事务提交时, 无条件执行事务的命令序列。
悲观锁:
顾名思义很悲观,每次去拿数据的时候都认为别人修改,所以每次在拿数据的时候都会上锁,这样如果中间有人想拿数据就会一直阻塞除非锁被释放获取到锁。传统的关系型数据库里,用到了很多种这种锁机制,比如行锁,表锁,写锁等
乐观锁:
顾名思义很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。
2、redis事务命令
1 discard
取消事务,放弃执行事务块内的所有命令。
2 exec
执行所有事务块内的命令。
事务中的命令序列将被执行(或者不被执行,比如乐观锁失败等)。该命令将返回响应数组,其内容对应事务中的命令执行结果。
3 multi
标记一个事务块的开始,该命令返回OK提示信息。
Redis不支持事务嵌套,执行多次MULTI命令和执行一次是相同的效果。嵌套执行MULTI命令时,Redis只是返回错误提示信息。
4 unwatch
取消 watch 命令对所有 key 的监视。
取消当前客户端对象的乐观锁key,该客户端对象的事务提交将变成无条件执行。
5 watch key [key ...]
监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
watch命令是开始执行乐观锁,该命令的参数是key(可以有多个), redis将执行watch命令的客户端对象和key进行关联,如果其他客户端修改了这些key,则执行watch命令的客户端将被设置乐观锁失败的标志。该命令必须在事务开始前执行,即在执行multi命令前执行watch命令,否则执行无效,并返回错误提示信息。
3、事务提交命令exec有可能会失败, 有三种类型的失败场景:
在事务提交之前,客户端执行的命令缓存失败。比如命令的语法错误(命令参数个数错误, 不支持的命令等等)。如果发生这种类型的错误,Redis将向客户端返回包含错误提示信息的响应;
事务提交时,之前缓存的命令有可能执行失败;
由于乐观锁失败,事务提交时,将丢弃之前缓存的所有命令序列。
4、使用乐观锁机制时,watch注意事项
redis事务和乐观锁一起使用时,事务将成为有条件提交。
watch命令必须在multi命令之前执行。 watch命令可以执行多次。
watch命令可以指定乐观锁的多个key,如果在事务过程中,任何一个key被其他客户端改变,则当前客户端的乐观锁失败,事务提交时,将丢弃所有命令序列。
多个客户端的watch命令可以指定相同的key。
watch命令指定乐观锁后,可以接着执行multi命令进入事务上下文,也可以在watch命令和multi命令之间执行其他命令。具体使用方式取决于场景需求,不在事务中的命令将立即被执行。
如果watch命令指定的乐观锁的key,被当前客户端改变,在事务提交时,乐观锁不会失败。
如果watch命令指定的乐观锁的key具有超时属性,并且该key在watch命令执行后, 在事务提交命令exec执行前超时, 则乐观锁不会失败。如果该key被其他客户端对象修改,则乐观锁失败。
以上是关于Redis 事务的主要内容,如果未能解决你的问题,请参考以下文章