02-redis篇 redis事务处理及使用方式

2023-10-28

目录

1. 事务简介: 

-> 1.1 必须满足: ACID四个特性(原子性,一致性,隔离性,持久性)

-> 1.2 简单理解: 一个业务,也可以看成是一个逻辑工作单元;

2. redis 操作事务的基本指令

-> 指令: 

 -> 图式: 

3.  模拟多事务操作(watch乐观锁)

3.1 不开启乐观锁watch操作

-> 按照执行指令提交的先后顺序

3.2 开启乐观锁watch操作

-> 3.2.1 A事务 先不提交

-> 3.2.2  B事务 直接提交后A在提交

-> 3.2.3 然后操作A事务提交

4. Jedis代码

4.1 (事务操作)

 4.2 事务 + 乐观锁


1. 事务简介: 

-> 1.1 必须满足: ACID四个特性(原子性,一致性,隔离性,持久性)

-> 1.2 简单理解: 一个业务,也可以看成是一个逻辑工作单元;

是为了保证业务的完整,数据的正确而推出的一种控制机制

2. redis 操作事务的基本指令

-> 指令: 

  • multi 开启事务
  • exec 提交事务
  • discard 取消事务
  • watch 监控,如果监控的值发生变化,则提交事务时会失败
  • unwatch 去掉监控

 -> 图式: 

 


3.  模拟多事务操作(watch乐观锁)

3.1 不开启乐观锁watch操作

-> 按照执行指令提交的先后顺序

3.2 开启乐观锁watch操作

-> 3.2.1 A事务 先不提交

-> 3.2.2  B事务 直接提交后A在提交

 

-> 3.2.3 然后操作A事务提交

 


4. Jedis代码

4.1 (事务操作)

package cn.pzy.transactionals;

import cn.pingzhuyan.jedisPool.JedisDataSourceLazy;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import static cn.pingzhuyan.jedisPool.JedisDataSourceLazy.PRIVATE_KEY;

public class JedisTransactionTests {

    @Test
    public void testTransactionals() {

        Transaction multi = null;
        //try里面的内容不重要 就是基础的jedis连接池
        try (Jedis jedis = JedisDataSourceLazy.lazyConnection(PRIVATE_KEY)) {
            jedis.set("aaa", "100");
            jedis.set("bbb", "200");
            //实现操作,aaa给bbb 100
            // 结果是 aaa 0  bbb 300

            //开启事务
            multi = jedis.multi();

           //执行业务操作
            multi.decrBy("aaa", 100);
            multi.incrBy("bbb", 100);

            /*模拟异常 开启则报错, 如下图*/
//            int n = 1 / 0;

            //提交事务
            multi.exec();
            String aaa = jedis.get("aaa");
            String bbb = jedis.get("bbb");
            System.out.println("aaa=" + aaa);
            System.out.println("bbb=" + bbb);
        } catch (Exception e) {
            if (multi != null) {
                System.out.println("事务处理中出现异常, 取消执行队列!!!");
                System.out.println(e.getMessage());
                multi.discard();
            }

        }
    }
}

 4.2 事务 + 乐观锁

[仍需测试, 感觉有点小问题]

package cn.pzy.transactionals;

import cn.pingzhuyan.jedisPool.JedisDataSourceLazy;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.util.List;
import java.util.Objects;

import static cn.pingzhuyan.jedisPool.JedisDataSourceLazy.PRIVATE_KEY;


public class Demo01 {

    public static void secKill() {
        Jedis jedis = null;
        Transaction multi = null;
        //try里面的内容不重要 就是基础的jedis连接池
        try {
            jedis = JedisDataSourceLazy.lazyConnection(PRIVATE_KEY);

            jedis.watch("ticket", "money");
            String ticket = jedis.get("ticket");
            if (ticket == null || Integer.parseInt(ticket) == 0) {
                System.out.println("已无库存!!!");
                throw new RuntimeException("已无库存");
            }

            multi = jedis.multi();

            multi.decr("ticket");
            multi.incrBy("money", 100);

            List<Object> exec = multi.exec();
            System.out.println(exec);

//            if (exec == null || Objects.equals(exec.size(), 0)) {
//                System.out.println("无命令执行!!!");
//                throw new RuntimeException("无命令执行");
//            }

        } catch (Exception e) {
            e.printStackTrace();
            if (multi != null) {
                System.out.println("取消事务!!!");
                multi.discard();
            }
        } finally {
            if (jedis != null) {
                System.out.println("锁和池释放!!!");
                jedis.unwatch();
                jedis.close();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Jedis jedis = JedisDataSourceLazy.lazyConnection(PRIVATE_KEY);
        jedis.set("ticket", "2");
        jedis.set("money", "0");

        new Thread(() -> {
            secKill();
            System.out.println("执行1");
        }).start();

        Thread.sleep(2);
        new Thread(() -> {
            secKill();
            System.out.println("执行2");
        }).start();
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

02-redis篇 redis事务处理及使用方式 的相关文章

随机推荐