• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Redis入门之:事务中的乐观和悲观详解

武飞扬头像
juejin
帮助93

Redis事务

定义

Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 Redis事务的主要作用就是串联多个命令防止别的命令插队。

Multi、Exec、discard?(SpringBoot怎么实现)

从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。

组队的过程中可以通过discard来放弃组队。

image.png

    //增加乐观锁
    jedis.watch(qtkey);

    //3.判断库存
    String qtkeystr = jedis.get(qtkey);
    if(qtkeystr==null || "".equals(qtkeystr.trim())) {
        System.out.println("未初始化库存");
        jedis.close();
        return false ;
    }

    int qt = Integer.parseInt(qtkeystr);
    if(qt<=0) {
        System.err.println("已经秒光");
        jedis.close();
        return false;
    }

    //增加事务
    Transaction multi = jedis.multi();

    //4.减少库存
    //jedis.decr(qtkey);
    multi.decr(qtkey);

    //5.加人
    //jedis.sadd(usrkey, uid);
    multi.sadd(usrkey, uid);

    //执行事务
    List<Object> list = multi.exec();

    //判断事务提交是否失败
    if(list==null || list.size()==0) {
        System.out.println("秒杀失败");
        jedis.close();
        return false;
    }
    System.err.println("秒杀成功");
    jedis.close();

错误处理

组队中某个命令出现了报告错误,执行时整个的所有队列都会被取消。 image.png image.png

此处在multi过程中,exec之前,我们对一个v1去increase 导致发生了错误,组队期间的所有东西都会不成功

***与MySQL的区别!!!

如果执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。 image.png

总结

在组队期间发生错误,就会回滚。

  • 而在执行阶段发生错误了,则不会回滚。

悲观锁

image.png

乐观锁

版本机制,类似CAS中的ABA问题解决 但这里不会循环去查询,而是直接就失败了? 想一想这里会不会引发其他的问题呢?

image.png

对比

image.png

秒杀库存变成负数问题

  • 乐观锁和悲观锁都能解决,因为在每次购买下单之前,都会先去检查一下
    • 乐观锁会去检查版本,发现版本号不一样了,直接就失败了!(那肯定不会出现负数的情况)
    • 而悲观锁呢? 悲观锁是等待上一个人执行完了,再来操作.这样可以保证不会出现负数的情况,同时也能够继续进行购买,不会说就此失败了!

乐观锁引发的库存遗留问题

解决--Lua脚本

将复杂的或者多步的redis操作,写为一个脚本,一次提交给redis执行,减少反复连接redis的次数。提升性能。 LUA脚本是类似redis事务,有一定的原子性,不会被其他命令插队,可以完成一些redis事务性的操作。 但是注意redis的lua脚本功能,只有在Redis 2.6以上的版本才可以使用。 利用lua脚本淘汰用户,解决超卖问题。 redis 2.6版本以后,通过lua脚本解决争抢问题,实际上是redis 利用其单线程的特性,用任务队列的方式解决多任务并发问题

watch

在执行multi之前,先执行watch key1 [key2],可以监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

事务三特性

  • 单独的隔离操作

​事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

  • 没有隔离级别的概念

​队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行

  • 不保证原子性

事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanehff
系列文章
更多 icon
同类精品
更多 icon
继续加载