Redis篇-3--原理篇2--Redis事务
1、概述
Redis 提供了简单的事务机制,Redis 事务的本质是一组命令的集合。当执行redis事务时,即一次性按照添加顺序依次执行这些命令,中间不会被打断或者干扰。
Redis 的事务机制并不像关系型数据库中的事务那样提供完整的ACID特性(原子性、一致性、隔离性和持久性),但它确实提供了一种方式来确保一组命令作为一个整体被执行。
2、redis事务的命令
Redis 事务通过 MULTI、EXEC、WATCH 和 DISCARD 这四个命令来实现。
(1)、MULTI
MULTI 命令用于标记一个事务块的开始。一旦接收到 MULTI,Redis 会将之后接收到的所有命令放入队列中,而不是立即执行。这些命令会在稍后的 EXEC调用时一起执行。
语法: MULTI
使用示例:
(2)、EXEC
EXEC 命令用于执行之前由 MULT` 标记的所有命令。它会按照它们被加入队列的顺序执行所有命令,并一次性返回所有命令的结果。
如果在 MULTI 和 EXEC之间有 WATCH 监视的键被修改,则 EXEC将返回 null,表示事务失败。
语法: EXEC
使用示例:
(3)、WATCH
WATCH 命令用于实现乐观锁。它允许你监视一个或多个键,在 EXEC 执行之前,如果这些键被其他客户端修改过,那么整个事务将不会执行,EXEC 会返回 nil。WATCH必须在 MULTI 之前调用。
语法: WATCH key [key …]
使用示例:
打开两个redis-cli客户端
1、右侧客户端先监听user:1000:credits值,在开启事务。
2、左侧客户端重置user:1000:credits的值为3;
3、右侧客户端在自增user:1000:credits的值,在提交事务
4、返回nil,因为有其他的客户端修改了监听的值,所以事务失败了。
(4)、DISCARD
DISCARD 命令用于取消一个事务,清空事务队列,并恢复到正常状态。这意味着在 MULTI 和 DISCARD 之间的所有命令都不会被执行。DISCARD 通常在事务执行前发现某些条件不满足时使用,以避免执行不必要的命令。
语法: DISCARD
使用示例:
(5)、watch实现Redis事务锁(了解下):
Redis 事务本身并不提供锁机制,但它可以通过 WATCH 命令和乐观锁的概念来处理并发问题。
如下图的示例中,两个客户端同时修改INCR user:1000:credits的值,就会出现问题。
左侧客户端看到的结果是,3自增之后变成了5,是不是很奇怪?如果换成卖票的场景,最后一张票被卖了两次,余量变成了-1,那不就出大问题了吗?
解决思路:在操作之前锁定要操作的数据,一旦发生变化,终止当前操作。
具体做法:对目标key 通过添加watch监视,这样在提交事务的时候如果发现key的值被修改了,就不会执行事务。如,最初watch的示例一般。
再注意下:
关系型数据库执行的锁为悲观锁,Redis的watch命令是乐观锁。如果不想要watch监听了,可以使用unwatch取消对所有 key 的监视。
一但执行 EXEC 开启事务的执行后,无论事务是否执行成功, WATCH 对变量的监控都将被取消。
当事务执行即使是失败后,也需重新执行WATCH命令对变量进行监控,并开启新的事务进行操作。
3、redis事务异常处理机制
在 Redis 事务中,如果命令集合中的某个命令发生了错误,Redis 的行为取决于错误的类型。Redis 事务并没有提供像关系型数据库那样的回滚机制。这意味着一旦 EXEC
被调用,所有排队的命令都会被执行,即使其中一些命令失败了。
Redis 事务中的“失败”有两种情况:
(1)、语法错误(命令解析错误)
这类错误发生在命令被加入到事务队列时(即在 MULTI 和 EXEC 之间)。如果命令存在语法错误或使用了不存在的命令,Redis 会立即返回错误信息,并且不会将其加入队列。如下:
此时你可以选择取消事务(通过 DISCARD),或继续添加其他命令,最终执行时只会执行语法正确的命令。
(2)、运行时错误(命令执行错误)
这类错误发生在 EXEC 执行期间。当 Redis 执行事务中的命令时,如果某个命令由于某些原因无法完成(例如试图对非整数键进行递增操作),该命令会失败,但事务中的其余命令仍然会继续执行。
Redis 会为每个命令保留执行结果,包括失败命令的结果(通常是一个错误信息)。
因此,EXEC的返回值是一个数组,其中包含了每个命令的执行结果,可以用来检查哪些命令成功了,哪些命令失败了。
学海无涯苦作舟!!!
原文地址:https://blog.csdn.net/qq_34207422/article/details/144382936
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!