Redis事务和锁机制

时间:2022-10-16 07:55:11

目录

一、事务和锁机制

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会将之前的命令队列中的命令依次执行。

Redis事务和锁机制

Redis事务和锁机制

Redis事务和锁机制

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

Redis事务和锁机制

Redis事务和锁机制

⚪事务的不成功情况

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

Redis事务和锁机制

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

Redis事务和锁机制

二、事务冲突

1.事务冲突的问题

Redis事务和锁机制2.悲观锁(Pessimistic Lock)

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

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

3.乐观锁 (Optimistic Lock)

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

Redis事务和锁机制4.WATCH key [key...] 

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

⭐示例:

Redis事务和锁机制

Redis事务和锁机制

5.redis事务的三个特性

①单独的隔离操作

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

②没有隔离级别的概念

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

③不保证原子性 

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

三、秒杀案例

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

Redis事务和锁机制

⚪基本功能实现

public class SecKill_redis {

	public static void main(String[] args) {
		Jedis jedis =new Jedis("192.168.XXX.XXX",6379);
		System.out.println(jedis.ping());
		jedis.close();
	}

	//秒杀过程
	public static boolean doSecKill(String uid,String prodid) throws IOException {
		//1.uid和prodid非空判断
		if(uid == null || prodid == null) {
			return false;
		}

		//2 连接redis
		Jedis jedis = new Jedis("192.168.XXX.XXX",6379);

		//3 拼接key
		// 3.1 库存key
		String kcKey = "sk:"+prodid+":qt";
		// 3.2 秒杀成功用户key
		String userKey = "sk:"+prodid+":user";

		//4 获取库存,如果库存null,秒杀还没有开始
		String kc = jedis.get(kcKey);
		if(kc == null) {
			System.out.println("秒杀还未开始,请耐心等待");
			jedis.close();
			return false;
		}

		// 5 判断用户是否重复秒杀操作
		if(jedis.sismember(userKey, uid)) {
			System.out.println("已经秒杀成功了,不能重复秒杀");
			jedis.close();
			return false;
		}

		//6 判断如果商品数量,库存数量小于1,秒杀结束
		if(Integer.parseInt(kc)<=0) {
			System.out.println("秒杀已经结束了");
			jedis.close();
			return false;
		}

		//7 秒杀过程
		if(results == null || results.size()==0) {
			System.out.println("秒杀失败~");
			jedis.close();
			return false;
		}

		//7.1 库存-1
		//jedis.decr(kcKey);
		//7.2 把秒杀成功用户添加清单里面
		//jedis.sadd(userKey,uid);

		System.out.println("秒杀成功!!!!!");
		jedis.close();
		return true;
	}
}

Redis事务和锁机制

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

Redis事务和锁机制

Redis事务和锁机制

Redis事务和锁机制

⚪使用ab模拟测试

①有网络

yum install httpd-tools

Redis事务和锁机制

输入y完成安装

Redis事务和锁机制

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

Redis事务和锁机制

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

Redis事务和锁机制

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