php 锁机制 stream,Php+redis+锁机制实现高并发秒杀抢购解决方案

一、加排它锁

$pdo=new PDO("mysql:dbname=demo;host=localhost","root","root");

$pdo->query('SET NAMES utf8');

$redis=new Redis();

$redis->connect('127.0.0.1', 6379);

$num=$redis->get("num");

if($num<=12)//假定库存只有12个

{

sleep(2);

$sql = "select * from goods where id=1 for update";

$stmt = $pdo->query($sql);

$res=$stmt->fetch(2);

if($res['num'])

{ $redis->incr('num');

$stmt = $pdo->exec("update goods set num=num-1 where id=1");

//自行写各种业务处理。。。

}

}

else{

echo "抢购结束";

}

二、php+redis乐观锁

$pdo=new PDO("mysql:dbname=demo;host=localhost","root","root");

$pdo->query('SET NAMES utf8');

$redis=new Redis();

$redis->connect('127.0.0.1', 6379);

$uid=md5(mt_rand(1,1000000));//模拟生成用户id

var_dump($redis->lrange('user',0,-1));

$num=$redis->get("num");

// $redis->del("num");

// $redis->del("user");

//die;

if($num>=3) exit("抢购结束");//假设只有3个库存量

$redis->watch('num');//监听key的变化,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断

//开始事务

$redis->multi();

$redis->incr('num');

sleep(2);

$result=$redis->exec(); //返回true表示执行成功,nil表示事务被中断

if($result)

{

$stmt = $pdo->exec("update goods set num=num-1 where id=1");

if($stmt){

echo "抢购成功";

$redis->lpush("user",$uid);//记录抢购成功的用户id

//自行写各种业务处理。。。

}

}

a4928f0d3ad7021295760e7c7c8a12ef.png

经过ab压测后,就再也不会出现超卖的情况啦,哈哈

三、最后一个用文件锁,性能也是最低的,不推荐使用

$redis=new Redis();

$redis->connect('127.0.0.1',6379);

$num=$redis->get('num');//购买数量

$ku=1;//库存量

if($num

$file=fopen('1.lock',"a");

if(flock($file,LOCK_EX))

{

$store=$redis->incr('num');

fwrite($file,$store);

sleep(5);

//自行写各种业务处理。。。

flock($file,LOCK_UN);

}

fclose($file);

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值