【Redis】Redis事务详解

Redis的事务(transaction)允许在一个单独的操作序列中执行多个命令,并保证这些命令在其他客户端无法中断的情况下执行。Redis通过MULTI、EXEC、DISCARD和WATCH命令来实现事务管理。

Redis事务的基本命令

  1. MULTI:开启一个事务块。
  2. EXEC:执行所有在事务块中排队的命令。
  3. DISCARD:取消事务,放弃事务块中的所有命令。
  4. WATCH:监视一个或多个键,如果在事务执行之前这些键被修改,那么事务将被取消。

Redis事务的使用步骤

  1. 使用MULTI命令开始一个事务。
  2. 执行一系列的命令,这些命令将被放入事务队列中,而不会立即执行。
  3. 使用EXEC命令提交事务,所有的命令将按顺序执行。
  4. 如果在事务开始后但在执行之前需要取消事务,可以使用DISCARD命令。

代码示例

下面是一个使用Jedis(Java的Redis客户端)来实现Redis事务的示例代码:

java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class RedisTransactionExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        try {
            // 清空当前数据库
            jedis.flushDB();

            // 开启一个事务
            Transaction transaction = jedis.multi();
            try {
                // 在事务中添加多个命令
                transaction.set("key1", "value1");
                transaction.set("key2", "value2");
                transaction.incr("counter");

                // 提交事务
                transaction.exec();
            } catch (Exception e) {
                // 如果发生任何异常,取消事务
                transaction.discard();
                e.printStackTrace();
            }

            // 验证结果
            System.out.println("key1: " + jedis.get("key1"));
            System.out.println("key2: " + jedis.get("key2"));
            System.out.println("counter: " + jedis.get("counter"));

        } finally {
            // 关闭连接
            jedis.close();
        }
    }
}

乐观锁(Optimistic Locking)

Redis的WATCH命令用于实现乐观锁。当一个或多个键被WATCH监视后,如果这些键在事务执行之前被其他客户端修改,事务将被取消。

WATCH命令示例

java 复制代码
public class RedisOptimisticLockingExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        try {
            // 清空当前数据库
            jedis.flushDB();

            // 设置初始值
            jedis.set("balance", "100");
            jedis.set("debt", "0");

            // 监视balance键
            jedis.watch("balance");

            int balance = Integer.parseInt(jedis.get("balance"));
            int debt = Integer.parseInt(jedis.get("debt"));
            int payment = 30;

            // 检查余额是否足够支付
            if (balance >= payment) {
                // 开启事务
                Transaction transaction = jedis.multi();
                try {
                    // 更新余额和债务
                    transaction.decrBy("balance", payment);
                    transaction.incrBy("debt", payment);

                    // 提交事务
                    transaction.exec();
                    System.out.println("Transaction successful");
                } catch (Exception e) {
                    transaction.discard();
                    System.out.println("Transaction failed");
                    e.printStackTrace();
                }
            } else {
                System.out.println("Insufficient balance");
            }

            // 验证结果
            System.out.println("balance: " + jedis.get("balance"));
            System.out.println("debt: " + jedis.get("debt"));

        } finally {
            // 取消监视
            jedis.unwatch();
            // 关闭连接
            jedis.close();
        }
    }
}

这个示例展示了如何在Redis中使用事务和WATCH命令来实现乐观锁。如果在事务提交之前balance键被其他客户端修改,事务将被取消。

相关推荐
阿里云大数据AI技术36 分钟前
鹰角网络基于阿里云EMR Serverless StarRocks的实时分析工程实践
数据库·数据分析
久笙&1 小时前
对象存储解决方案:MinIO 的架构与代码实战
数据库·python·架构
L2ncE1 小时前
高并发场景数据与一致性的简单思考
java·后端·架构
武昌库里写JAVA1 小时前
使用 Java 开发 Android 应用:Kotlin 与 Java 的混合编程
java·vue.js·spring boot·sql·学习
小指纹1 小时前
河南萌新联赛2025第(六)场:郑州大学
java·开发语言·数据结构·c++·算法
叶~璃1 小时前
云计算:企业数字化转型的核心引擎
java
码luffyliu1 小时前
MySQL:MVCC机制及其在Java秋招中的高频考点
java·数据库·mysql·事务·并发·mvcc
程序员鱼皮1 小时前
这套 Java 监控系统太香了!我连夜给项目加上了
java·前端·ai·程序员·开发·软件开发
水涵幽树1 小时前
MySQL 时间筛选避坑指南:为什么格式化字符串比较会出错?
数据库·后端·sql·mysql·database
岁忧1 小时前
(nice!!!)(LeetCode 每日一题) 1277. 统计全为 1 的正方形子矩阵 (动态规划)
java·c++·算法·leetcode·矩阵·go·动态规划