• Redis事务和锁机制


    目录

    一、事务和锁机制

    1.定义

    Redis事务的主要作用

    2.Multi、Exec、discard

    ⚪事务的不成功情况

    二、事务冲突

    1.事务冲突的问题

    ​编辑2.悲观锁(Pessimistic Lock)

    3.乐观锁 (Optimistic Lock)

    ​编辑4.WATCH key [key...] 

    ⭐示例:

    5.redis事务的三个特性

    ①单独的隔离操作

    ②没有隔离级别的概念

    ③不保证原子性 

    三、秒杀案例

    ⭐解决计数器和人员记录的事务操作

    ⚪基本功能实现

    ​编辑

    ⚪使用ab模拟测试

    ①有网络

    ②没有网络

    ③通过ab进行测试


    一、事务和锁机制

    1.定义

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

    Redis事务的主要作用

    串联多个命令防止别的命令插队。

    2.Multi、Exec、discard

    从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,

    直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。

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

    ⚪事务的不成功情况

    • 任何一个命令错误,最终都不会成功

    •  如果执行中某个命令出了错误,只有它会报错,其它的正常执行

    二、事务冲突

    1.事务冲突的问题

    2.悲观锁(Pessimistic Lock)

    每次去拿数据的时候都认为别人会修改,所以每次拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。

    传统的关系型数据库里边就用到了很多这种锁的机制,比如行锁,表锁等,读锁,写锁等,都是在操作之前先上锁

    3.乐观锁 (Optimistic Lock)

    乐观锁,顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

    4.WATCH key [key...] 

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

    ⭐示例:

    5.redis事务的三个特性

    ①单独的隔离操作

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

    ②没有隔离级别的概念

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

    ③不保证原子性 

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

    三、秒杀案例

    ⭐解决计数器和人员记录的事务操作

    ⚪基本功能实现

    1. public class SecKill_redis {
    2. public static void main(String[] args) {
    3. Jedis jedis =new Jedis("192.168.XXX.XXX",6379);
    4. System.out.println(jedis.ping());
    5. jedis.close();
    6. }
    7. //秒杀过程
    8. public static boolean doSecKill(String uid,String prodid) throws IOException {
    9. //1.uid和prodid非空判断
    10. if(uid == null || prodid == null) {
    11. return false;
    12. }
    13. //2 连接redis
    14. Jedis jedis = new Jedis("192.168.XXX.XXX",6379);
    15. //3 拼接key
    16. // 3.1 库存key
    17. String kcKey = "sk:"+prodid+":qt";
    18. // 3.2 秒杀成功用户key
    19. String userKey = "sk:"+prodid+":user";
    20. //4 获取库存,如果库存null,秒杀还没有开始
    21. String kc = jedis.get(kcKey);
    22. if(kc == null) {
    23. System.out.println("秒杀还未开始,请耐心等待");
    24. jedis.close();
    25. return false;
    26. }
    27. // 5 判断用户是否重复秒杀操作
    28. if(jedis.sismember(userKey, uid)) {
    29. System.out.println("已经秒杀成功了,不能重复秒杀");
    30. jedis.close();
    31. return false;
    32. }
    33. //6 判断如果商品数量,库存数量小于1,秒杀结束
    34. if(Integer.parseInt(kc)<=0) {
    35. System.out.println("秒杀已经结束了");
    36. jedis.close();
    37. return false;
    38. }
    39. //7 秒杀过程
    40. if(results == null || results.size()==0) {
    41. System.out.println("秒杀失败~");
    42. jedis.close();
    43. return false;
    44. }
    45. //7.1 库存-1
    46. //jedis.decr(kcKey);
    47. //7.2 把秒杀成功用户添加清单里面
    48. //jedis.sadd(userKey,uid);
    49. System.out.println("秒杀成功!!!!!");
    50. jedis.close();
    51. return true;
    52. }
    53. }

    进行一次点击后,库存数量减一 

    ⚪使用ab模拟测试

    ①有网络

    yum install httpd-tools

    输入y完成安装

    使用ab --help查看如何使用

    1. Options are:
    2. -n requests 本次总请求数
    3. -c concurrency 并发数
    4. -t timelimit 基础压测最大时间(秒),基于-n 50000的情况下最大测试时间,默认不显示。
    5. -s timeout 请求超时时间(秒),默认30秒
    6. -b windowsize 缓冲区大小(字节)
    7. -B address Address to bind to when making outgoing connections
    8. -p postfile POST请求文件,需要设置 -T
    9. -u putfile PUT请求文件. 需要设置 -T
    10. -T content-type POST/PUT请求header中的content-type值,默认是'text/plain'
    11. -v verbosity 显示多少故障信息,1/2/3/4
    12. -w 在html中显示结果
    13. -i 使用head请求,默认是get
    14. -x attributes 设置table属性
    15. -y attributes 设置tr属性
    16. -z attributes 设置th属性
    17. -C attribute 添加cookie, 如:'Apache=1234',可重复
    18. -H attribute 添加header, 如:'Accept-Encoding: gzip',追加常规header后面,可重复。
    19. -A attribute 添加WWW认证信息, 格式'user:pwd'
    20. -P attribute 添加基础身份认证信息,格式'user:pwd'
    21. -X proxy:port 使用的代理服务端口
    22. -V 显示版本
    23. -k 使用http连接保持功能
    24. -d 不显示时间百分比分布.
    25. -S 不显示中位数和警告
    26. -q 总请求数大于150时,不显示测试请求进度(Benchmarking localhost)。
    27. -g filename 输出测试数据到指定文件.
    28. -e filename 输出百分比CSV文件
    29. -r 收到错误信息不退出
    30. -h 显示帮助信息
    31. -Z ciphersuite 指定SSL/TLS密码套件,参考openssl
    32. -f protocol 指定SSL/TLS协议,如:(SSL3, TLS1, TLS1.1, TLS1.2 or ALL)

    ②没有网络

    (1) 进入cd  /run/media/root/CentOS 7 x86_64/Packages(路径跟centos6不同)

    (2) 顺序安装

    apr-1.4.8-3.el7.x86_64.rpm

    apr-util-1.5.2-6.el7.x86_64.rpm

    httpd-tools-2.4.6-67.el7.centos.x86_64.rpm 

    ③通过ab进行测试

    ab -n 1000 -c 100 -p ~/postfile  -T application/x-www-form-urlencoded

    http://192.168.XXX.XXX:8081/Seckill/doseckill

    • -n 1000:请求的数量为1000
    • -c 100:并发数量为100
    • -p ~/postfile  :postfile提交参数      

    (新建一个文档,名称为profile,内容为prodid=0101&)  

    • http://192.168.2.115:8081/Seckill/doseckill  :地址 

  • 相关阅读:
    Nginx配置文件详解
    大数据Hadoop之——DorisDB核心概念介绍与简单使用(StarRocks)
    机器学习常见知识点 2:决策树
    【Linux内核】线程设置 线程调度 线程通信
    【电商运营】网上商店如何利用好自己的营销数据达成目标?
    G : 最大流问题
    javaweb中的转发与重定向
    云ES使用集群限流插件(aliyun-qos)
    FCoE测试重启调试记录
    安装独立版 Python
  • 原文地址:https://blog.csdn.net/m0_52982868/article/details/127290262