PHP实现高并发下的秒杀功能–Laravel

namespace App\Http\Controllers\SecKill;


use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class SecKillController extends Controller
{

/**
* 往redis的隊列中添加庫存(用於測試的數據)
*
*/
public function setAddRedis(){
$store=150;
$res=Redis::llen('goods_store');
echo $res;
$count=$store-$res;
for($i=0;$i<$count;$i++){
Redis::lpush('goods_store',1);
}
echo Redis::llen('goods_store');
}

//生成唯一订单号
public function build_order_no(){
return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}

/**
* 使用redis队列,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,推荐使用(mysql事务在高并发下性能下降很厉害,文件锁的方式也是)
* @param $goods_id
* @return string
*/
public function getGood($goods_id){
$price =10;
$count = Redis::lpop("goods_store");
if(!$count){
return "error:no store redis";
}
$order_sn=$this->build_order_no();

DB::insert('insert into ih_order (order_sn,user_id,goods_id,price) values (?, ?,?,?)', [$order_sn, rand(1,15),$goods_id,$price]);

$res = DB::update('update in_store set store_number = store_number-1 where goods_id = ?', [$goods_id]);
if($res){
return "库存减少成功";
} else{
return "库存减少失敗";
}
}

public function doLog($log){
file_put_contents("test.txt",$log.'\r\n',FILE_APPEND);
}

/**
*
* desc 在事务中对数据进行加锁,当事务进行提交(commit)或者回滚(rollBack)时都会取消锁。
* 单纯的开启一个事务,并不会对事务中的数据进行加锁,只会保证数据的完整性.其他数据是否可以访问,不能保证数据库的数据单一操作
* @param $goods_id
* @return bool
*/
public function getGoodByMysql($goods_id){
// 开启事务
DB::beginTransaction();
try {
// 需要处理的逻辑 doSomething;
$res = DB::table("in_store")->where(['goods_id'=>$goods_id])->sharedLock()->first();
//对事务中数据进行加锁(悲观锁)
if($res->store_number) {
$store_number = $res->store_number-1;
$num = DB::table('in_store')->where('goods_id',$goods_id)->decrement('store_number');
if($num) {
// 提交事务
DB::commit();
$msg = "减少库存成功";
} else {
$msg = "减少库存失败";
}
} else {
$msg ="库存不够";
}
DB::rollBack();
return $msg;
} catch (Exception $e) {
// 数据回滚, 当try中的语句抛出异常。
DB::rollBack();
return false;
// 执行一些提醒操作等等...
}

}

}

转载于:https://www.cnblogs.com/vinzen/p/9804276.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/426599.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vuex的个人理解

看官方文档看的一脸懵逼&#xff0c;后来看到了一篇比较容易理解的博文&#xff0c;大概写下自己的理解 一、vuex是什么 是基于vue的状态管理模式&#xff0c;一般用于解决大型项目中子组件向父组件传递数据的问题 二、基本概念 1、state 需要使用store的数据存储在state里&…

java验证码的代码_java实用验证码的实现代码

本文为大家分享了java实用验证码的实现代码&#xff0c;供大家参考&#xff0c;具体内容如下1、ValidCodepackage validImg;import java.awt.Color;import java.io.IOException;import java.util.Random;import javax.servlet.ServletException;import javax.servlet.http.Http…

java学习(37):二维数组

/4 利用嵌套循环完成以下二维数组的遍历&#xff0c;体会二维数组或多维数组元素的遍历方法及每个维数数组元素的下标特点。/ import java.util.Scanner; public class test06 { public static void main(String[] args){ Scanner in new Scanner(System.in); System.out.print…

java.util.stream_java.util.stream.Stream 接口中的常用方法

流模型的操作很丰富&#xff0c;下面介绍一些常用的API。这些方法可以被分成两种&#xff1a;延迟方法返回值类型仍然是 Stream 接口自身类型的方法&#xff0c;因此支持链式调用。(除了终结方法外&#xff0c;其余方 法均为延迟方法。)终结方法返回值类型不再是 Stream 接口自…

SRM 698 div1 RepeatString

250pts RepeatString 题意&#xff1a;问最少修改多少次将一个字符串修改为AA的形式。可以插入一个字符&#xff0c;删除一个字符&#xff0c;修改字符。 思路&#xff1a;枚举分界点&#xff0c;然后dp一下。 1 /*2 * Author: mjt3 * Date: 2018-10-17 19:50:164 * Last Mod…

java学习(38):数组排序(直接排序)

/5 有一个长度为10的int类型数组,存储了10个年龄数据,利用Eclipse工具设计一个java控制台程序, 完成将这个int类型数组中年龄进行算法对比,将10个年龄重新存储在新数组中,新数组中存储年龄应符合以下规则: 降序排列 ./ import java.util.Scanner; public class test07 { public…

java学习(39):九九乘法表

public class test08{ public static void main(String[] args){ for(int i1;i<9;i){ System.out.println(); for(int j1;j<i;j){ System.out.print("\t"i""j""(ij)); } } } }

java 私有变量访问_Java - 访问私有实例变量

我需要从以下类列表(Species.java)访问私有变量&#xff0c;以便在KlingonOx.java类中使用它们。KlingonOx.java类的目的是确定大象物种的种群数量将大于克林贡牛种的数量。这是Species.java类&#xff1a;import java.util.Scanner;public class Species{private String name;…

setState是异步还是同步?

react中setState是同步还是异步困扰了好久&#xff0c;今天终于有了答案&#xff1b;它既是同步的&#xff0c;也是异步的&#xff1b; 批量更新&#xff1a; 加入我在页面上写三个setState去分别 componentDidMount() {this.setState({ val: this.state.val 1 }) console.log…

java学习(40):成员实例的定义和访问

定义一个student类 public class student { String name;//输入姓名 int age;//输入年龄 String address;//输入地址 char sex;//输入性别 double height;//输入身高 } 定义一个teststudent类 //成员实例的定义和访问 public class testStudent { public static void main(Stri…

简易计算器 java_终于写出一个简单的计算器了

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼import javax.swing.*;import java.awt.event.*;import java.awt.*;import java.util.Scanner;//import java.util.Scanner;public class Jisuanji {JLabel JLabel1;JLabel JLabel2;JLabel JLabel3;//标签JFrame mainJFrame;//布局…

2018.10.20 NOIP模拟 蛋糕(线段树+贪心/lis)

传送门 听说是最长反链衍生出的对偶定理就能秒了。 本蒟蒻直接用线段树模拟维护的。 对于第一维排序。 维护第二维的偏序关系可以借助线段树/树状数组维护逆序对的思想建立权值线段树贪心求解。代码 转载于:https://www.cnblogs.com/ldxcaicai/p/10084858.html

java学习(41):成员实例的定义和访问续

定义一个studentstudy类 /1 使用Eclipse编写控制台应用程, 编写一个用来表示学生的java类&#xff0c; 并在类中定义描述学生特征的属性&#xff0c;姓名&#xff0c;年龄&#xff0c;性别&#xff0c;身高&#xff0c;体重和电话&#xff0c; 要求属性设置为私有访问级别并为私…

brew 安装 mysql5.7_Mac——brew替换源地址安装配置mysql@5.7版本

问题描述&#xff1a;使用brew方式安装mysql&#xff0c;存在以下问题&#xff1a;1.由于mysql已经升级到8.x版本&#xff0c;会默认安装8.x版本&#xff0c;会对之前部分特性不友好支持&#xff1b;2.brew默认安装源下载响应时间非常慢&#xff0c;下载时间过长容易超时&#…

ftp的本地用户搭建

前期的准备跟虚拟用户一样&#xff0c;就是配置文件不一样 修改配置文件 就是共享的都是自己的账号的家目录&#xff0c;然后启动服务就可以了 本地登陆的都是自己的账号密码 ftp本地的黑名单&#xff0c; 转载于:https://www.cnblogs.com/cash-su/p/9824553.html

java学习(42):巩固练习

定义一个testjava类 /*4 编写一个TestStudentOverrideConstructor.java类&#xff0c; 包含main方法&#xff0c;从控制台接收用户输入的学生信息&#xff0c;包括学生姓名&#xff0c;性别和年龄&#xff0c;使用带参数的构造器创建学生对象并将接收到的输入传递给这个构造器参…

错误解决:常出现在iis搭建网站

不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定 在全新安装的IIS7下搭建网站&#xff0c;访问页面时出现错误信息如下&#xff1a; 配置错误 不能在此路径中使用此配置节。如果在父级别上锁定了该节&#xff0c;便会出现这种情况。锁定是默认…

java收发邮寄_JavaMail收发邮件的一般流程与主要方法

1、Properties属性类Properties p new Properties();p.put(key, value);key-| mail.smtp.host-| mail.smtp.port-| mail.smtp.auth->"true":"false"2、生成Authenticator的子类Overrideprotected PasswordAuthenticationgetPasswordAuthentication(){r…

Java中TreeMap和TreeSet的底层实现

TreeSet底层则采用NavigableMap这个接口来保存TreeSet集合&#xff0c;而实际上NavigableMap只是一个接口&#xff0c;实际上TreeSet还是用TreeMap来保存set元素。 TreeSet初始化的时候会new 一个TreeMap进行初始化&#xff1b; private transient NavigableMap<E,Object>…

oracle 11g数据库数据操作(亲测)

oracle 11g安装和oracle数据库监听配置就不说了&#xff0c;直接说数据库的相关操作 建立 wiicare 用户 create directory dump_dir as ‘d:\test\dump’; 使用 PLSQL Developer 连接数据库 登陆数据库&#xff0c;用户名:system 密码: 123456 连接为&#xff1a;sysdba 新建表…