Redis事务和管道

一、Redis事务

1、定义

可以一次执行多个命令,本质上是一组命令的集合。一个事务中的所有命令都会序列化,按顺序的串行化执行而不会被其他命令插入,不能加塞。

2、作用

一个队列中,一次性、顺序性、排他性的执行一系列命令。

3、特性

单独的隔离操作
Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的
没有隔离级别的概念
因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了
不保证原子性
Redis的事务 不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
排它性
Redis会保证一个事务内的命令依次执行,而不会被其它命令插入

4、使用方式

MULTI:开启事务       EXEC:执行事务      DISCARD:取消事务

 

 注意:Redis不提供事务回滚功能,开发者必须在事务执行出错后,自行恢复数据库状态。

5、Watch监控

Redis使用Watch提供乐观锁定,watch命令是一种乐观锁的实现,Redis在修改的时候会检测数据是否被更改,如果更改了,则执行失败。

悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。

乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。 

一旦执行了EXEC之前加的监控锁都会被取消掉了,当客户端连接丢失的时候,所有东西取消监视

二、Redis管道

1、如何优化频繁命令往返造成的性能瓶颈?

管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完完毕后,通过一条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间

2、管道定义

管道是为了解决RTT往返回时,仅仅是将命令打包一次性发送,对整个Redis的执行不造成影响。

管道(pipeline)实现的原理是队列先进先出特性就保证数据的顺序性。

3、Pipeline与原生批量命令对比

命令原子性执行实现方式
pipeline批量执行不同命令服务端和客户端共同实现
原生批量命令一次只能执行一种命令服务端实现

4、Pipeline与事务对比

命令原子性执行阻塞
pipeline一次性将多条命令发送到服务器不会阻塞其他命令
事务一条一条发,事务只有在接收到EXEC命令后才会执行会阻塞其他命令执行

5、Pipeline注意事项

①pipeline缓冲的指令只是会依次执行,不保证原子性,如果执行中指令发生异常,将会继续执行后续指令。

②使用pipeline组装的命令个数不能太多,不然数据量过大客户端阻塞的时间可能更久,同时服务端此时也被迫回复一个队列答复,占用很多内存。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当使用Gin和Redis进行事务操作时,你可以按照以下代码示例进行操作: ```go package main import ( "fmt" "github.com/gin-gonic/gin" "github.com/go-redis/redis/v8" ) func main() { r := gin.Default() // 创建 Redis 客户端 rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", // Redis服务器地址 Password: "", // Redis密码,如果没有设置密码则为空 DB: 0, // Redis数据库索引(0默认使用的数据库) }) // 设置路由和处理程序 r.POST("/transaction", func(c *gin.Context) { // 开始 Redis 事务 pipe := rdb.TxPipeline() // 在事务中执行多个命令 pipe.Incr("counter") pipe.Set("key", "value") // 执行事务,并获取结果 _, err := pipe.Exec() if err != nil { // 处理事务执行失败的情况 c.JSON(500, gin.H{ "message": "Transaction failed", }) return } // 事务执行成功的情况 c.JSON(200, gin.H{ "message": "Transaction successful", }) }) // 启动服务器 if err := r.Run(":8080"); err != nil { fmt.Println("Failed to start server:", err) } } ``` 以上代码演示了如何在Gin中使用Redis进行事务操作。在路由处理程序中,我们创建了一个Redis事务管道(`pipe`),然后在事务中执行多个Redis命令(例如,递增计数器和设置键值对)。最后,我们调用`Exec()`方法执行事务,并根据执行结果返回相应的JSON响应。 请确保在运行此代码之前已经安装了Gin和Go Redis客户端库。 希望对你有所帮助!如果你有更多问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IsLuNaTiC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值