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

64图裁剪php_swoole+PHP实现自动取消订单,还原库存等操作

一、业务场景:当客户下单在指定的时间内如果没有付款,那我们需要将这笔订单取消掉,比如好的处理方法是运用延时取消,这里我们用到

一、业务场景:当客户下单在指定的时间内如果没有付款,那我们需要将这笔订单取消掉,比如好的处理方法是运用延时取消,这里我们用到了swoole,运用swoole的异步毫秒定时器不会影响到当前程序的运行,具体参考:https://wiki.swoole.com/wiki/page/319.html

二、说明,order_status为1时代表客户下单确定,为2时代表客户已付款,为0时代表订单已取消(正是swoole来做的),下面的代表我没有用框架,比较纯的PHP代表方便理解和应用

三、举例说明,库存表csdn_product_stock产品ID为1的产品库存数量为20,产品ID为2的库存数量为40,然后客户下单一笔产品ID1减10,产品ID2减20,所以库存表只够2次下单,例子中10秒后自动还原库存,如下图:

图解:1、第一次下完单产品ID1库存从20减到了10,产品ID2库存从40减到了20;2、第二次下完单产品ID的库存为0了,产品ID2的库存也为0了,3、第三次下单时,程序提示Out of stock;4、过了10秒钟(每个订单下单后往后推10秒),客户两次下单,由于没有付款(csdn_order表的order_status为1),产品1和产品2的库存被还原了(csdn_order表的order_status变为0),客户又可以继续下单了

f9a83579e34f7a73663a513031b6dfd0.gif

1、所需要sql数据库表

DROP TABLE IF EXISTS `csdn_order`;
CREATE TABLE `csdn_order` (`order_id` int(10) unsigned NOT NULL AUTO_INCREMENT,`order_amount` float(10,2) unsigned NOT NULL DEFAULT '0.00',`user_name` varchar(64) CHARACTER SET latin1 NOT NULL DEFAULT '',`order_status` tinyint(2) unsigned NOT NULL DEFAULT '0',`date_created` datetime NOT NULL,PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;DROP TABLE IF EXISTS `csdn_order_detail`;
CREATE TABLE `csdn_order_detail` (`detail_id` int(10) unsigned NOT NULL AUTO_INCREMENT,`order_id` int(10) unsigned NOT NULL,`product_id` int(10) NOT NULL,`product_price` float(10,2) NOT NULL,`product_number` smallint(4) unsigned NOT NULL DEFAULT '0',`date_created` datetime NOT NULL,PRIMARY KEY (`detail_id`),KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;DROP TABLE IF EXISTS `csdn_product_stock`;
CREATE TABLE `csdn_product_stock` (`auto_id` int(10) unsigned NOT NULL AUTO_INCREMENT,`product_id` int(10) NOT NULL,`product_stock_number` int(10) unsigned NOT NULL,`date_modified` datetime NOT NULL,PRIMARY KEY (`auto_id`),KEY `idx_product_id` (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;INSERT INTO `csdn_product_stock` VALUES ('1', '1', '20', '2018-09-13 19:36:19');
INSERT INTO `csdn_product_stock` VALUES ('2', '2', '40', '2018-09-13 19:36:19');

2、数据库配置信息:config.php

$dbHost = "192.168.0.110";
$dbUser = "root";
$dbPassword = "123456";
$dbName = "test123";
?>

3、order_submit.php,生成订单

require("config.php");
try {$pdo &#61; new PDO("mysql:host&#61;" . $dbHost . ";dbname&#61;" . $dbName, $dbUser, $dbPassword, array(PDO::ATTR_PERSISTENT &#61;> true));$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);$orderInfo &#61; array(&#39;order_amount&#39; &#61;> 10.92,&#39;user_name&#39; &#61;> &#39;yusan&#39;,&#39;order_status&#39; &#61;> 1,&#39;date_created&#39; &#61;> &#39;now()&#39;,&#39;product_lit&#39; &#61;> array(0 &#61;> array(&#39;product_id&#39; &#61;> 1,&#39;product_price&#39; &#61;> 5.00,&#39;product_number&#39; &#61;> 10,&#39;date_created&#39; &#61;> &#39;now()&#39;),1 &#61;> array(&#39;product_id&#39; &#61;> 2,&#39;product_price&#39; &#61;> 5.92,&#39;product_number&#39; &#61;> 20,&#39;date_created&#39; &#61;> &#39;now()&#39;)));try{$pdo->beginTransaction();//开启事务处理$sql &#61; &#39;insert into csdn_order (order_amount, user_name, order_status, date_created) values (:orderAmount, :userName, :orderStatus, now())&#39;;$stmt &#61; $pdo->prepare($sql); $affectedRows &#61; $stmt->execute(array(&#39;:orderAmount&#39; &#61;> $orderInfo[&#39;order_amount&#39;], &#39;:userName&#39; &#61;> $orderInfo[&#39;user_name&#39;], &#39;:orderStatus&#39; &#61;> $orderInfo[&#39;order_status&#39;]));$orderId &#61; $pdo->lastInsertId();if(!$affectedRows) {throw new PDOException("Failure to submit order!");}foreach($orderInfo[&#39;product_lit&#39;] as $productInfo) {$sqlProductDetail &#61; &#39;insert into csdn_order_detail (order_id, product_id, product_price, product_number, date_created) values (:orderId, :productId, :productPrice, :productNumber, now())&#39;;$stmtProductDetail &#61; $pdo->prepare($sqlProductDetail); $stmtProductDetail->execute(array(&#39;:orderId&#39; &#61;> $orderId, &#39;:productId&#39; &#61;> $productInfo[&#39;product_id&#39;], &#39;:productPrice&#39; &#61;> $productInfo[&#39;product_price&#39;], &#39;:productNumber&#39; &#61;> $productInfo[&#39;product_number&#39;]));$sqlCheck &#61; "select product_stock_number from csdn_product_stock where product_id&#61;:productId"; $stmtCheck &#61; $pdo->prepare($sqlCheck); $stmtCheck->execute(array(&#39;:productId&#39; &#61;> $productInfo[&#39;product_id&#39;])); $rowCheck &#61; $stmtCheck->fetch(PDO::FETCH_ASSOC);if($rowCheck[&#39;product_stock_number&#39;] <$productInfo[&#39;product_number&#39;]) {throw new PDOException("Out of stock, Failure to submit order!");}$sqlProductStock &#61; &#39;update csdn_product_stock set product_stock_number&#61;product_stock_number-:productNumber, date_modified&#61;now() where product_id&#61;:productId&#39;;$stmtProductStock &#61; $pdo->prepare($sqlProductStock); $stmtProductStock->execute(array(&#39;:productNumber&#39; &#61;> $productInfo[&#39;product_number&#39;], &#39;:productId&#39; &#61;> $productInfo[&#39;product_id&#39;]));$affectedRowsProductStock &#61; $stmtProductStock->rowCount();//库存没有正常扣除&#xff0c;失败&#xff0c;库存表里的product_stock_number设置了为非负数//如果库存不足时&#xff0c;sql异常&#xff1a;SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in &#39;(&#96;test&#96;.&#96;csdn_product_stock&#96;.&#96;product_stock_number&#96; - 20)&#39;if($affectedRowsProductStock <&#61; 0) {throw new PDOException("Out of stock, Failure to submit order!");}}echo "Successful, Order Id is&#xff1a;" . $orderId ."&#xff0c;Order Amount is&#xff1a;" . $orderInfo[&#39;order_amount&#39;] . "。";$pdo->commit();//提交事务//exec("php order_cancel.php -a" . $orderId . " &");pclose(popen(&#39;php order_cancel.php -a &#39; . $orderId . &#39; &&#39;, &#39;w&#39;));//system("php order_cancel.php -a" . $orderId . " &", $phpResult);//echo $phpResult;}catch(PDOException $e){echo $e->getMessage();$pdo->rollback();}$pdo &#61; null;
} catch (PDOException $e) {echo $e->getMessage();
}
?>

4、order_cancel.php&#xff0c;这个方法主要就是做订单自动取消&#xff0c;并还原库存的业务处理

require("config.php");
$queryString &#61; getopt(&#39;a:&#39;);
$userParams &#61; array($queryString);
appendLog(date("Y-m-d H:i:s") . "t" . $queryString[&#39;a&#39;] . "t" . "start");try {$pdo &#61; new PDO("mysql:host&#61;" . $dbHost . ";dbname&#61;" . $dbName, $dbUser, $dbPassword, array(PDO::ATTR_PERSISTENT &#61;> true));$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);swoole_timer_after(10000, function ($queryString) {global $queryString, $pdo;try{$pdo->beginTransaction();//开启事务处理$orderId &#61; $queryString[&#39;a&#39;]; $sql &#61; "select order_status from csdn_order where order_id&#61;:orderId"; $stmt &#61; $pdo->prepare($sql); $stmt->execute(array(&#39;:orderId&#39; &#61;> $orderId)); $row &#61; $stmt->fetch(PDO::FETCH_ASSOC);//$row[&#39;order_status&#39;] &#61;&#61;&#61; "1"代表已下单&#xff0c;但未付款&#xff0c;我们还原库存只针对未付款的订单if(isset($row[&#39;order_status&#39;]) && $row[&#39;order_status&#39;] &#61;&#61;&#61; "1") {$sqlOrderDetail &#61; "select product_id, product_number from csdn_order_detail where order_id&#61;:orderId"; $stmtOrderDetail &#61; $pdo->prepare($sqlOrderDetail); $stmtOrderDetail->execute(array(&#39;:orderId&#39; &#61;> $orderId)); while($rowOrderDetail &#61; $stmtOrderDetail->fetch(PDO::FETCH_ASSOC)) {$sqlRestoreStock &#61; "update csdn_product_stock set product_stock_number&#61;product_stock_number &#43; :productNumber, date_modified&#61;now() where product_id&#61;:productId"; $stmtRestoreStock &#61; $pdo->prepare($sqlRestoreStock);$stmtRestoreStock->execute(array(&#39;:productNumber&#39; &#61;> $rowOrderDetail[&#39;product_number&#39;], &#39;:productId&#39; &#61;> $rowOrderDetail[&#39;product_id&#39;]));}$sqlRestoreOrder &#61; "update csdn_order set order_status&#61;:orderStatus where order_id&#61;:orderId"; $stmtRestoreOrder &#61; $pdo->prepare($sqlRestoreOrder);$stmtRestoreOrder->execute(array(&#39;:orderStatus&#39; &#61;> 0, &#39;:orderId&#39; &#61;> $orderId));}$pdo->commit();//提交事务}catch(PDOException $e){echo $e->getMessage();$pdo->rollback();}$pdo &#61; null;appendLog(date("Y-m-d H:i:s") . "t" . $queryString[&#39;a&#39;] . "t" . "endt" . json_encode($queryString));}, $pdo);} catch (PDOException $e) {echo $e->getMessage();
}
function appendLog($str) {$dir &#61; &#39;log.txt&#39;;$fh &#61; fopen($dir, "a");fwrite($fh, $str . "n");fclose($fh);
}
?>

以上内容希望帮助到大家&#xff0c;很多PHPer在进阶的时候总会遇到一些问题和瓶颈&#xff0c;业务代码写多了没有方向感&#xff0c;不知道该从那里入手去提升&#xff0c;对此我整理了一些资料&#xff0c;包括但不限于&#xff1a;分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6&#xff0c;laravel&#xff0c;YII2&#xff0c;Redis&#xff0c;Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家&#xff0c;需要请戳这里链接 或 者关注咱们下面的知乎专栏
PHP架构师圈子​zhuanlan.zhihu.com
6a3397ad15505668b4adb00ed17972fb.png

来源链接&#xff1a;https://blog.csdn.net/WanTianwen/article/details/82693677




推荐阅读
  • MySQL锁机制详解
    本文深入探讨了MySQL中的锁机制,包括表级锁、行级锁以及元数据锁,通过实例详细解释了各种锁的工作原理及其应用场景。同时,文章还介绍了如何通过锁来优化数据库性能,避免常见的并发问题。 ... [详细]
  • 闭包函数,即匿名函数,在PHP中通过Closure类表示。本文将探讨如何访问闭包内的static、this及parameter等关键属性。 ... [详细]
  • 本文介绍了如何通过ARM编译器组件重定向标准C运行时库的I/O函数,以适应不同的硬件平台。原文链接:https://www.keil.com/pack/doc/compiler/RetargetIO/html/retarget_overview.html ... [详细]
  • 交互式左右滑动导航菜单设计
    本文介绍了一种使用HTML和JavaScript实现的左右可点击滑动导航菜单的方法,适用于需要展示多个链接或项目的网页布局。 ... [详细]
  • 本文探讨了如何利用SqlDependency执行复杂的SQL查询,并确保在多线程环境下的安全性与效率。 ... [详细]
  • Python数据类型6 字典
    字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包 ... [详细]
  • 本文详细介绍了ActivityManagerService (AMS) 的工作原理及其在Android系统中的重要角色。AMS作为system_server进程的一部分,在系统启动时加载,负责管理和协调应用程序中的Activity和服务(Service)。文章将通过具体的接口图和通信流程,帮助读者更好地理解AMS的工作机制。 ... [详细]
  • JavaScript:简洁与复杂之间的平衡
    本文探讨了在编写JavaScript教程时,如何在保持内容简洁的同时,确保初学者能够理解并应用实际开发中的复杂问题。文章通过具体示例分析了不同层次的JavaScript代码实现。 ... [详细]
  • 微信小程序中实现位置获取的全面指南
    本文详细介绍了如何在微信小程序中实现地理位置的获取,包括通过微信官方API和腾讯地图API两种方式。文中不仅涵盖了必要的准备工作,如申请开发者密钥、下载并配置SDK等,还提供了处理用户授权及位置信息获取的具体代码示例。 ... [详细]
  • 本文介绍了如何通过源码编译和PECL命令来升级Swoole扩展,详细记录了可能遇到的问题及解决方案。 ... [详细]
  • 本文介绍了如何使用Workman框架构建一个功能全面的即时通讯系统,该系统不仅支持一对一聊天、群组聊天,还集成了视频会议和实时音视频通话功能,同时提供了红包发送等附加功能。 ... [详细]
  • Swoole加密机制的安全性分析与破解可能性探讨
    本文深入分析了Swoole框架的加密机制,探讨了其在实际应用中的安全性,并评估了潜在的破解可能性。研究结果表明,尽管Swoole的加密算法在大多数情况下能够提供有效的安全保护,但在特定场景下仍存在被攻击的风险。文章还提出了一些改进措施,以增强系统的整体安全性。 ... [详细]
  • 本指南旨在帮助Swoole初学者快速掌握异步并发编程的基本概念和实践方法。通过实例演示,我们将使用Swoole PHP扩展构建一个简单的客户端与服务器模型,并实现基本的通信功能。首先,我们将从客户端的实现入手(文件名为:client.php)。 ... [详细]
  • 本文详细介绍如何在 Windows 环境下安装 Ubuntu 12.04 版本的 Linux 操作系统,包括必要的软件下载、配置步骤以及注意事项。 ... [详细]
  • 本文详细介绍了如何正确安装Java EE SDK,并解决在安装过程中可能遇到的问题,特别是关于servlet代码在Apache Tomcat 10中无法运行的情况。 ... [详细]
author-avatar
斿荡
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有