热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

laravel解决超卖的几个方法

数据库字段

数据库字段


1 错误的示范

  1. function test1()
  2. {
  3. $id = request()->input('id');
  4. $product = Product::where('id', $id)->firstOrFail();
  5. if ($product->num <= 0) return "卖光啦!!";
  6. $product->decrement('num'); //库存减1
  7. return "success";
  8. }

使用 go 模拟并发

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/PeterYangs/tools/http"
  5. "sync"
  6. )
  7. func main() {
  8. client := http.Client()
  9. wait := sync.WaitGroup{}
  10. for i := 0; i < 50; i++ {
  11. wait.Add(1)
  12. go func(w *sync.WaitGroup) {
  13. defer w.Done()
  14. res, _ := client.Request().GetToString("http://www.api/test1?id=1")
  15. fmt.Println(res)
  16. }(&wait)
  17. }
  18. wait.Wait()
  19. }


2 方案1 redis 原子锁

  1. function test2()
  2. {
  3. $id = request()->input('id');
  4. $lock = \Cache::lock("product_" . $id, 10);
  5. try {
  6. //最多等待5秒,5秒后未获取到锁,则抛出异常
  7. $lock->block(5);
  8. $product = Product::where('id', $id)->firstOrFail();
  9. if ($product->num <= 0) {
  10. return "卖光啦!!";
  11. }
  12. $product->decrement('num');
  13. return 'success';
  14. }catch (LockTimeoutException $e) {
  15. return '当前人数过多';
  16. } finally {
  17. optional($lock)->release();
  18. }
  19. }


3 方案2 mysql 悲观锁

  1. function test3()
  2. {
  3. $id = request()->input('id');
  4. try {
  5. \DB::beginTransaction();
  6. $product = Product::where('id', $id)->lockForUpdate()->first();
  7. if ($product->num <= 0) {
  8. return "卖光啦!!";
  9. }
  10. $product->decrement('num');
  11. \DB::commit();
  12. return "success";
  13. } catch (\Exception $exception) {
  14. }
  15. }

库存正常


4 方案3 mysql 乐观锁

  1. function test4()
  2. {
  3. $id = request()->input('id');
  4. $product = Product::where('id', $id)->first();
  5. if ($product->num <= 0) {
  6. return "卖光啦!!";
  7. }
  8. //修改前检查库存和之前是否一致,不一致说明已经有变动,则放弃更改
  9. $res = \DB::update('UPDATE `product` SET num = num -1 WHERE id = ? AND num=?', [$id, $product->num]);
  10. if (!$res) {
  11. return '当前人数过多';
  12. }
  13. return 'success';
  14. }

库存正常
优化乐观锁
修改库存的 sql 修改为
\DB::update(‘UPDATE product SET num = num -1 WHERE id = ? AND num-1 >= 0’, [$id]);


5 方案4 redis 存储库存

  1. function test5()
  2. {
  3. $id = request()->input('id');
  4. $num = Redis::command('get', ['product_' . $id]);
  5. if ($num <= 0) {
  6. return "卖完啦!";
  7. }
  8. $re = Redis::command('decrby', ['product_' . $id, 1]);
  9. //减多了回滚
  10. if ($re < 0) {
  11. Redis::command('incrby', ['product_' . $id, 1]);
  12. return "卖完啦!";
  13. }
  14. return 'success';
  15. }

库存正常
原文链接:https://blog.csdn.net/weixin_41882200/article/details/119249367
欢迎补充


推荐阅读
  • 利用Selenium与ChromeDriver实现豆瓣网页全屏截图
    本文介绍了一种使用Selenium和ChromeDriver结合Python代码,轻松实现对豆瓣网站进行完整页面截图的方法。该方法不仅简单易行,而且解决了新版Selenium不再支持PhantomJS的问题。 ... [详细]
  • C#设计模式学习笔记:观察者模式解析
    本文将探讨观察者模式的基本概念、应用场景及其在C#中的实现方法。通过借鉴《Head First Design Patterns》和维基百科等资源,详细介绍该模式的工作原理,并提供具体代码示例。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 嵌入式开发环境搭建与文件传输指南
    本文详细介绍了如何为嵌入式应用开发搭建必要的软硬件环境,并提供了通过串口和网线两种方式将文件传输到开发板的具体步骤。适合Linux开发初学者参考。 ... [详细]
  • 解决TensorFlow CPU版本安装中的依赖问题
    本文记录了在安装CPU版本的TensorFlow过程中遇到的依赖问题及解决方案,特别是numpy版本不匹配和动态链接库(DLL)错误。通过详细的步骤说明和专业建议,帮助读者顺利安装并使用TensorFlow。 ... [详细]
  • Python 内存管理机制详解
    本文深入探讨了Python的内存管理机制,涵盖了垃圾回收、引用计数和内存池机制。通过具体示例和专业解释,帮助读者理解Python如何高效地管理和释放内存资源。 ... [详细]
  • 如何清除Chrome浏览器地址栏的特定历史记录
    在使用Chrome浏览器时,你可能会发现地址栏保存了大量浏览记录。有时你可能希望删除某些特定的历史记录而不影响其他数据。本文将详细介绍如何单独删除地址栏中的特定记录以及批量清除所有历史记录的方法。 ... [详细]
  • 本文介绍如何使用 Angular 6 的 HttpClient 模块来获取 HTTP 响应头,包括代码示例和常见问题的解决方案。 ... [详细]
  • 基于Node.js、Express、MongoDB和Socket.io的实时聊天应用开发
    本文详细介绍了使用Node.js、Express、MongoDB和Socket.io构建的实时聊天应用程序。涵盖项目结构、技术栈选择及关键依赖项的配置。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 小编给大家分享一下如何移除URL中的index.php,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收 ... [详细]
  • 本文详细介绍了在XAMPP环境中如何修改Apache和MySQL的默认端口号,并确保WordPress能够正常访问。同时,提供了针对Go语言社区和Golang开发者的相关建议。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 本文详细介绍了如何在PHP中删除数组中的指定元素、第一个元素和最后一个元素,并提供了具体的代码示例和相关函数的使用说明。 ... [详细]
  • 本教程将详细介绍Python中的包、模块、类和函数的概念,探讨它们在程序中的作用及相互关系,帮助读者更好地理解Python的结构化编程。 ... [详细]
author-avatar
阳光无限好1981
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有