• 如何在Go项目中使用Redis事务
  • 发布于 2个月前
  • 121 热度
    0 评论
  • 小熊
  • 0 粉丝 30 篇博客
  •   
一  什么是Redis事务
什么是Redis事务?引用官方的回答如下:Redis事务允许将一组命令以单个步骤的方式执行,事务涉及到MULTI、EXEC、DISCARD和WATCH等命令。Redis事务提供了两个重要的保证:
1.事务中的所有命令按顺序被串行化和执行。在执行Redis事务期间,不会在中间阶段服务于另一个客户端发送的请求。这确保了命令的执行作为一个单独的隔离操作。
2.EXEC命令触发执行事务中的所有命令。如果客户端在调用EXEC命令之前失去与服务器的连接,则不会执行任何操作。相反,如果调用了EXEC命令,则会执行所有操作。

总结:Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。


二 Redis事务相关命令和使用
2.1  MULTI、EXEC、DISCARD、WATCH和 UNWATCH是 Redis 事务相关的命令。
MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。
EXEC:执行事务中的所有操作命令。
DISCARD:取消事务,放弃执行事务块中的所有命令。
WATCH:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。

UNWATCH:取消WATCH对所有key的监视。


2.2 使用示例
2.2.1 标准事务过程
27.0.0.1:6379> multi  //开启一个事务
OK
127.0.0.1:6379(TX)> set k1 111 //赋值
QUEUED
127.0.0.1:6379(TX)> set k2 222 //赋值
QUEUED
127.0.0.1:6379(TX)> set k3 333 //赋值
QUEUED
127.0.0.1:6379(TX)> exec // 执行
1) OK
2) OK
3) OK
127.0.0.1:6379> get k2 // 获取对应值
"222"
2.2.2 取消事务
127.0.0.1:6379> multi //开启事务
OK
127.0.0.1:6379(TX)> set k4 444
QUEUED
127.0.0.1:6379(TX)> set k5 555
QUEUED
127.0.0.1:6379(TX)> discard // 取消事务
OK
127.0.0.1:6379> exec // 执行就会报错
(error) ERR EXEC without MULTI
127.0.0.1:6379> get k4
(nil)
2.2.3 事务监视
127.0.0.1:6379> set k8 8 //先给k8赋值
OK
127.0.0.1:6379> watch k8 //监视k8
OK
127.0.0.1:6379> set k8 888 //修改k8值
OK
127.0.0.1:6379> multi //开启事务
OK
127.0.0.1:6379(TX)> set k8 10000 //修改k8值
QUEUED
127.0.0.1:6379(TX)> set k9 1999 //给k9赋值
QUEUED
127.0.0.1:6379(TX)> exec //执行事务以及结果
(nil)
127.0.0.1:6379> get k8
"888"
127.0.0.1:6379> get k9
(nil)
三 基于Go实现Redis事务示例
package main

import (
  "context"
  "fmt"
  "log"

  "github.com/go-redis/redis/v8"
)

func main() {
  // 创建Redis客户端连接
  rdb := redis.NewClient(&redis.Options{
    Addr:     "localhost:6379", // Redis服务器地址
    Password: "",               // Redis密码,如果没有设置则留空
    DB:       0,                // 默认数据库
  })
  // 堆代码 duidaima.com
  // 开始事务
  tx := rdb.TxPipeline()

  // 将多个命令添加到事务队列中
  tx.Set(context.Background(), "key1", "value1", 0)
  tx.Set(context.Background(), "key2", "value2", 0)

  // 执行事务并获取结果
  _, err := tx.Exec(context.Background())
  if err != nil {
    log.Fatal(err)
  }

  // 关闭Redis客户端连接
  err = rdb.Close()
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println("Transaction executed successfully!")
}
在上述示例中,我们使用 go-redis/redis 库创建了一个Redis客户端连接,并使用 rdb.TxPipeline() 方法创建了一个事务管道。然后,我们将多个Redis命令(这里是 SET 命令)依次添加到事务管道中。需要注意的是,这些命令并不会立即执行,而是暂存在事务队列中。最后,调用 tx.Exec(context.Background()) 方法来执行整个事务,并获取执行结果。

需要注意的是,当有错误发生时,可以使用 tx.Discard() 方法取消事务,并丢弃队列中的所有命令。
用户评论