10. Redis之事务管理

Redis之事务管理

原文:https://ooyhao.github.io/categories/DB/Redis/

事务简介

Redis事务可以一次执行多个命令,并且带有以下三个重要的保证:

  • 批量操作在EXEC命令前被放入队列缓存。
  • 收到EXEC命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

一个事务从开始到执行会经历一下三个阶段:

  1. 开启事务
  2. 命令入列
  3. 执行事务

事务相关命令

序号命令描述
1discarddiscard 命令用于取消事务,放弃执行事务块内的所有命令
2execexec命令用于执行所有事务块内的命令
3multimulti 命令用于标记一个事务块的开始。
事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由EXEC命令原子性(atomic)地执行
4unwatchunwatch 命令用于取消watch命令对所有key的监视
5watchWATCH key [key ...] watch 命令用于监视一个或多个key,如果再事务执行之前这个或这些key被其他命令所改动,那么事务将被打断。

实例

下面执行一个事务的例子。它是以 multi 开始一个事务,然后将多个命令入列到事务中,最后通过exec命令来触发事务,一并执行事务中的所有命令。如下:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set book-name 'springboot in action'
QUEUED
127.0.0.1:6379> get book-name
QUEUED
127.0.0.1:6379> sadd tag spring springboot java
QUEUED
127.0.0.1:6379> smembers tag
QUEUED
127.0.0.1:6379> exec
1) OK
2) "springboot in action"
3) (integer) 3
4) 1) "java"
   2) "springboot"
   3) "spring"

单个Redis命令的执行是原子性的,但是Redis没有在事务上增加任何原子性的机制,所以Redis事务的执行并不是原子性的。事务可以理解为一个打包的批量执行脚本,但批量执行并不是原子性的操作,中间某条执行失败也不会导致前面的命令进行回滚,也不会导致后面的执行不会被执行。

例如:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a aaa
QUEUED
127.0.0.1:6379> set b bbb
QUEUED
127.0.0.1:6379> set c ccc
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) OK

说明:如果再set b bbb处失败了,set a 已经成功执行,不会进行回滚。并且set c还会继续执行。

事务中的异常情况

redis 中事务的异常情况总的来说,分为两种:

  1. 进入队列之前就能发现的错误,比如命令输错。
  2. 执行exec命令之后才能发现的错误,比如给一个非数字字符加1。

那么对于这两种不同的异常,redis中有不同的处理策略。对于第一种错误,服务器会对命令入列失败的情况进行记录,并在客户端调用exec命令时,拒绝执行并自动放弃这个事务。如下:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379>
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3 3 3
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) ERR syntax error
4) OK
127.0.0.1:6379> keys *
1) "k4"
2) "k1"
3) "k2"

而对于第二种情况,redis并没有对它们进行特别处理,即使事务中有某个/某些命令在执行时产生了错误,事务中的其他命令仍然会继续执行。如下:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 vv
QUEUED
127.0.0.1:6379> incr k1
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range
127.0.0.1:6379> get k1
"vv"

不同于关系型数据库,redis的事务中出错时不会进行事务回滚。即redis的事务更像是命令操作的批处理。对此,官方解释如下:

Redis命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面。这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。因为不需要对回滚进行支持,所有redis的内部可以保持简单且快速。

watch 命令

事务中的watch命令可以用来监控一个key,通过一个或多个key。通过这种监控,我们可以为redis事务提供(CAS)行为。如果有至少一个被watch监视的键在exec执行之前被修改了,那么整个事务都会被取消。exec返回nil-reply 来表示事务已经失败。如下:

127.0.0.1:6379> set k4 2
OK
127.0.0.1:6379> watch k4
OK
127.0.0.1:6379> set k4 5
OK
127.0.0.1:6379> get k4
"5"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k4 8
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get k4
"5"

watch 命令可以监控一个或多个key。一旦其中一个键被修改(或删除)。之后的事务就不会执行,监控一直持续到exec命令(事务中的命令是在exec之后才执行的,exec命令执行完之后被监控的键会自动被unwatch).

通过unwatch 命令,可以取消对一个key的监控。如下:

127.0.0.1:6379> set kk 3
OK
127.0.0.1:6379> watch kk
OK
127.0.0.1:6379> set kk 5
OK
127.0.0.1:6379> get kk
"5"
127.0.0.1:6379> unwatch
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set kk 9
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> get kk
"9"

关于Redis的事务问题就先到这了。

部分参考自:http://www.javaboy.org/2019/0615/redis-pub-sub.html

https://www.runoob.com/redis/redis-transactions.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
# fat FAT ,基于springboot , 使用zookeeper,redis , spring async , spring transactionManager的强一致性分布式事务解决方案 ## 框架介绍 纯编码方式,强一致性。<br> 使用redis/zookeeper作为注册中心 ,代理事务的执行,使用spring async异步处理事务线程。<br> 基于注解使用,对业务代码可以说是零入侵,目前内置适配spring-cloud(Feign调用) , dubbo。<br> 同时具备一定的扩展性与兼容性,因为存在自定义的服务框架,或者以后会涌现出更多的流行分布式服务框架,所以会提供一些组件适配自定义服务框架。 ## Maven依赖 ```java <dependency> <groupId>com.github.cjyican</groupId> <artifactId>fat-common</artifactId> <version>1.0.6-RELEASE</version> </dependency> ``` ## 使用示例 ### step0:SpringBootApplication加上@EnableFat注解 ```java @SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableFeignClients @EnableFat public class FatboyEurekaRibbonApplication { public static void main(String[] args) { SpringApplication.run(FatboyEurekaRibbonApplication.class, args); } } ``` ### step1:配置注册中心 使用redis/zookeeper作为注册中心,优先使用zookeeper。为隔离业务使用的redis和注册中心的redis,提供了一套属性配置。 在业务redis/zookeeper作为注册中心与注册中心相同时,也需要配置。 请保证各个服务的注册中心配置一致,否则无法协调分布式事务。 ```java #Fat # Redis数据库索引(默认为0) fat.redis.database=0 # Redis服务器地址 fat.redis.host= # Redis服务器连接端口 fat.redis.port=6379 # Redis服务器连接密码(默认为空) fat.redis.password= # 连接池最大连接数(使用负值表示没有限制) fat.redis.pool.max-active=20 # 连接池最大阻塞等待时间(使用负值表示没有限制) fat.redis.pool.max-wait=-1 # 连接池中的最大空闲连接 fat.redis.pool.max-idle=10 # 连接池中的最小空闲连接 fat.redis.pool.min-idle=2 # 连接超时时间(毫秒) fat.redis.timeout=1000 # 集群模式,如有配置,将优先使用集群 fat.redis.cluster.nodes=x.x.x.x:x,x.x.x.x:x # zookeeper服务器地址 fat.zookeeper.host=x.x.x.x:x,x.x.x.x:x # zookeeper活跃时间 fat.zookeeper.sessionTimeout=x.x.x.x:x,x.x.x.x:x ``` 应用标识,与spirng.application.name一致,必须配置 ```java spring.application.name=fatboy-eureka-ribbon ``` ### step2:服务入口方法加入注解@FatServiceRegister注册 在需要开启分布式事务管理的入口方法中加入注解@FatServiceRegister,注意不要重复添加。dubbo的直接加在serviceImpl.method上面就可以 ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
teamdev.redis.dll 是一个 Redis 数据库的 C# 客户端库,用于与 Redis 数据库进行通信和交互。Redis 是一个开源的高性能键值对存储数据库,常用于缓存、会话管理、消息队列等场景。 teamdev.redis.dll 提供了丰富的功能和方法,使开发者能够方便地连接到 Redis 数据库,并对其进行读写操作。它支持字符串、哈希、列表、集合、有序集合等多种数据类型的操作,还提供了事务和管道等高级功能,以及对 Redis 的发布与订阅功能的支持。 通过使用 teamdev.redis.dll,开发者可以轻松地在 C# 项目中使用 Redis 数据库,并利用其高性能和丰富的功能来提升应用程序的性能和扩展性。例如,可以将经常访问的数据缓存到 Redis 中,以减少数据库的查询压力;通过使用 Redis 的发布与订阅功能,实现实时消息推送或实时数据更新等功能。 teamdev.redis.dll 还提供了一些高级功能,如分布式锁和限流等,可以帮助开发者解决并发和性能问题。同时,它还支持 Redis Sentinel 和 Redis Cluster,使开发者能够在分布式环境中轻松管理和扩展 Redis 数据库。 总而言之,teamdev.redis.dll 是一个强大且易于使用的 Redis C# 客户端库,为开发者提供了方便、高效地与 Redis 数据库交互的工具。它的出现使得开发者能够更好地利用 Redis 的优势,并将其应用于各种场景中,从而提升应用程序的性能和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值