宿迁腾云网络网站建设公司

腾云网络 八年经验专注网站建设
  • 首页
  • 服务项目
    • 网站建设
    • 微信小程序
    • APP开发
    • SEO优化
  • 建站费用
  • 成功案例
    • 网站建设案例
    • 小程序案例
    • APP开发案例
    • SEO优化案例
  • 行业动态
    • 网站建设
    • SEO优化
    • 技术日志
  • 联系我们
    • 关于我们
首页 > 行业动态 > 技术日志 > swoole的自动取消订单还原库存等操作教程

swoole的自动取消订单还原库存等操作教程

2019-05-06

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


二、说明,order_status为1时代表客户下单确定,为2时代表客户已付款,为0时代表订单已取消(正是swoole来做的)


三、举例说明,库存表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),客户又可以继续下单了


swoole的自动取消订单还原库存等操作教程(图1)


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');


下面贴出来纯手工PHP,很多同学用了原生PHP,就不会运用到框架里去,其实都一样的,不要想得那么复杂就是了。只要一点就是你用多了,你就会这样觉得咯。


配置文件config.php  ,这个在框架的话,基本上都是配置好了。

<?php
$dbHost = "192.168.23.110";
$dbUser = "root";
$dbPassword = "123456";
$dbName = "test";
?>

swoole都是用在linux系统里的,这里的host你可以自己搭建虚拟主机,也可以网上购买属于自己的服务器


订单提交的文件order_submit.php,这里对订单生成,同时扣除库存的一系列操作

<?php
require("config.php");
try {
    $pdo = new PDO("mysql:host=" . $dbHost . ";dbname=" . $dbName, $dbUser, $dbPassword, array(PDO::ATTR_PERSISTENT => true));
    $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $orderInfo = array(
        'order_amount' => 10.92,
        'user_name' => 'yusan',
        'order_status' => 1,
        'date_created' => 'now()',
        'product_lit' => array(
            0 => array(
                'product_id' => 1,
                'product_price' => 5.00,
                'product_number' => 10,
                'date_created' => 'now()'
            ),
            1 => array(
                'product_id' => 2,
                'product_price' => 5.92,
                'product_number' => 20,
                'date_created' => 'now()'
            )
        )
    );

    try{
        $pdo->beginTransaction();//开启事务处理

        $sql = 'insert into csdn_order (order_amount, user_name, order_status, date_created) values (:orderAmount, :userName, :orderStatus, now())';
        $stmt = $pdo->prepare($sql);  
        $affectedRows = $stmt->execute(array(':orderAmount' => $orderInfo['order_amount'], ':userName' => $orderInfo['user_name'], ':orderStatus' => $orderInfo['order_status']));
        $orderId = $pdo->lastInsertId();
        if(!$affectedRows) {
            throw new PDOException("Failure to submit order!");
        }
        foreach($orderInfo['product_lit'] as $productInfo) {

            $sqlProductDetail = 'insert into csdn_order_detail (order_id, product_id, product_price, product_number, date_created) values (:orderId, :productId, :productPrice, :productNumber, now())';
            $stmtProductDetail = $pdo->prepare($sqlProductDetail);  
            $stmtProductDetail->execute(array(':orderId' => $orderId, ':productId' =>  $productInfo['product_id'], ':productPrice' => $productInfo['product_price'], ':productNumber' => $productInfo['product_number']));

            $sqlCheck = "select product_stock_number from csdn_product_stock where product_id=:productId";  
            $stmtCheck = $pdo->prepare($sqlCheck);  
            $stmtCheck->execute(array(':productId' => $productInfo['product_id']));  
            $rowCheck = $stmtCheck->fetch(PDO::FETCH_ASSOC);
            if($rowCheck['product_stock_number'] < $productInfo['product_number']) {
                throw new PDOException("Out of stock, Failure to submit order!");
            }


            $sqlProductStock = 'update csdn_product_stock set product_stock_number=product_stock_number-:productNumber, date_modified=now() where product_id=:productId';
            $stmtProductStock = $pdo->prepare($sqlProductStock);  
            $stmtProductStock->execute(array(':productNumber' => $productInfo['product_number'], ':productId' => $productInfo['product_id']));
            $affectedRowsProductStock = $stmtProductStock->rowCount();

            //库存没有正常扣除,失败,库存表里的product_stock_number设置了为非负数
            //如果库存不足时,sql异常:SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(`test`.`csdn_product_stock`.`product_stock_number` - 20)'
            if($affectedRowsProductStock <= 0) {
                throw new PDOException("Out of stock, Failure to submit order!");
            }
        }
        echo "Successful, Order Id is:" . $orderId .",Order Amount is:" . $orderInfo['order_amount'] . "。";
        $pdo->commit();//提交事务
        //exec("php order_cancel.php -a" . $orderId . " &");
        pclose(popen('php order_cancel.php -a ' . $orderId . ' &', 'w'));
        //system("php order_cancel.php -a" . $orderId . " &", $phpResult);
        //echo $phpResult;
    }catch(PDOException $e){
        echo $e->getMessage();
        $pdo->rollback();
    }
    $pdo = null;
} catch (PDOException $e) {
    echo $e->getMessage();
}
?>

订单的延时处理order_cancel.php

<?php
require("config.php");
$queryString = getopt('a:');
$userParams = array($queryString);
appendLog(date("Y-m-d H:i:s") . "\t" . $queryString['a'] . "\t" . "start");

try {
    $pdo = new PDO("mysql:host=" . $dbHost . ";dbname=" . $dbName, $dbUser, $dbPassword, array(PDO::ATTR_PERSISTENT => 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 = $queryString['a'];  
            $sql = "select order_status from csdn_order where order_id=:orderId";  
            $stmt = $pdo->prepare($sql);  
            $stmt->execute(array(':orderId' => $orderId));  
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            //$row['order_status'] === "1"代表已下单,但未付款,我们还原库存只针对未付款的订单
            if(isset($row['order_status']) && $row['order_status'] === "1") {
                $sqlOrderDetail = "select product_id, product_number from csdn_order_detail where order_id=:orderId";  
                $stmtOrderDetail = $pdo->prepare($sqlOrderDetail);  
                $stmtOrderDetail->execute(array(':orderId' => $orderId));  
                while($rowOrderDetail = $stmtOrderDetail->fetch(PDO::FETCH_ASSOC)) {
                    $sqlRestoreStock = "update csdn_product_stock set product_stock_number=product_stock_number + :productNumber, date_modified=now() where product_id=:productId";  
                    $stmtRestoreStock = $pdo->prepare($sqlRestoreStock);
                    $stmtRestoreStock->execute(array(':productNumber' => $rowOrderDetail['product_number'], ':productId' => $rowOrderDetail['product_id']));
                }

                $sqlRestoreOrder = "update csdn_order set order_status=:orderStatus where order_id=:orderId";  
                $stmtRestoreOrder = $pdo->prepare($sqlRestoreOrder);
                $stmtRestoreOrder->execute(array(':orderStatus' => 0, ':orderId' => $orderId));
            }

            $pdo->commit();//提交事务
        }catch(PDOException $e){
            echo $e->getMessage();
            $pdo->rollback();
        }
        $pdo = null;

        appendLog(date("Y-m-d H:i:s") . "\t" . $queryString['a'] . "\t" . "end\t" . json_encode($queryString));
    }, $pdo);

} catch (PDOException $e) {
    echo $e->getMessage();
}
function appendLog($str) {
    $dir = 'log.txt';
    $fh = fopen($dir, "a");
    fwrite($fh, $str . "\n");
    fclose($fh);
}
?>


Tag:
网站制作公众号

宿迁腾云网络网站建设公司 | 网站开发 | 网站制作 | 网站优化

咨询电话:13160355545

上一篇

返回栏目

下一篇

免责声明:本站所有文章和图片均来自用户分享和网络收集,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系网站客服处理。

热推

  • php程序员怎么开发网站2016年企业简介“城市通商城”泗阳站招聘会计启事微信小程序后端php开发
  • php开发典型模块大全光盘Node.js应用的热更新是不是就完美无缺了呢?我们接着看典型模块与项目实战大全光盘
  • 微信公众平台开发教程 php一门怎么与公众号的对接,实现一些回复文字内容 微信公众号开发教程php
  • erp开源框架 php一下Java部分框架和开源项目总结(一)Javaphp erp 开源
  • 免费php开源企业网站通常一个建站公司帮助客户建站的这些公司是如何帮助企业制作网站的php企业开源
  • Descriptionstringmb_convert_encoding,(stringin_charset,,stringstr,)
  • php游戏开发框架PHP学习第三阶段阶段学习周期及安装、SVN使用详解【】 php框架开发教程 pdf
  • 8月编程语言排行榜出炉:它稳了!教育2021-08-21
  • php 统计访问量代码“四川人口普查”微信小程序正式上线(图)网站访问人数统计代码
  • php session实现单点登录单点登录系统的分析与设计与分析(一)php session登录

相关

标签

seo(1182) 市场营销(661) 网站制作(573) 网站建设(564) 搜索引擎(553) 网站(482) PHP(361) 编程语言(345) 建站(294) 关键词排名优化(267) 网站建设公司(245) 优化(216) seo排名(207) 域名(190) 软件(171) 网站优化(148) 搜索引擎优化(146) 外链(141) 科技(136) 网站关键词(124) 网站排名优化(123) 域名服务器(120) 网站排名(107) 时政(103) 排名优化(95) 搜索引擎收录(93) 网站设计(92) 电子商务(88) 引擎(86) 移动互联网(85) 开发框架(79) 开发(75) 网站服务器(74) 框架(68) 前端开发(68) 网站分析(66) 网站建设方案(65) 关键(64) 流量(63) 源码(62) 百度优化(62) 网站权重(61) 开放源代码(59) seo培训(53) 网页设计(51) 百度(51) php框架(50) 网站建设知识(50) 大数据(50) 谷歌(49)
宿迁腾云网络网站建设公司
网站建设
  • 私人定制
  • 标准模板建站
  • 经济模板建站
精品模板

宿迁腾云网络网站建设公司

联系电话:13160355545

公司地址:江苏省宿迁市丽景湾华庭北门都市花园公寓9楼907

联系邮箱:admin@tyweb.net

全国分站
  • 北京
  • 广东
  • 东莞 广州 中山 深圳 惠州 江门 珠海 汕头 佛山 湛江 河源 肇庆 潮州 清远 韶关 揭阳 阳江 云浮 茂名 梅州 汕尾
  • 山东
  • 济南 青岛 临沂 济宁 菏泽 烟台 泰安 淄博 潍坊 日照 威海 滨州 东营 聊城 德州 莱芜 枣庄
  • 江苏
  • 苏州 徐州 盐城 无锡 南京 南通 连云港 常州 扬州 镇江 淮安 泰州 宿迁
  • 河南
  • 郑州 南阳 新乡 安阳 洛阳 信阳 平顶山 周口 商丘 开封 焦作 驻马店 濮阳 三门峡 漯河 许昌 鹤壁 济源
  • 上海
  • 河北
  • 石家庄 唐山 保定 邯郸 邢台 沧州 秦皇岛 张家口 衡水 廊坊 承德
  • 浙江
  • 温州 宁波 杭州 台州 嘉兴 金华 湖州 绍兴 舟山 丽水 衢州
  • 陕西
  • 西安 咸阳 宝鸡 汉中 渭南 安康 榆林 商洛 延安 铜川
  • 湖南
  • 长沙 邵阳 常德 衡阳 株洲 湘潭 永州 岳阳 怀化 郴州 娄底 益阳 张家界 湘西
  • 重庆
  • 福建
  • 漳州 泉州 厦门 福州 莆田 宁德 三明 南平 龙岩
  • 天津
  • 云南
  • 昆明 红河 大理 文山 德宏 曲靖 昭通 楚雄 保山 玉溪 丽江 临沧 思茅 西双版纳 怒江 迪庆
  • 四川
  • 成都 绵阳 广元 达州 南充 德阳 广安 阿坝 巴中 遂宁 内江 凉山 攀枝花 乐山 自贡 泸州 雅安 宜宾 资阳 眉山 甘孜
  • 广西
  • 贵港 玉林 北海 南宁 柳州 桂林 梧州 钦州 来宾 河池 百色 贺州 崇左 防城港
  • 安徽
  • 芜湖 合肥 六安 宿州 阜阳 安庆 马鞍山 蚌埠 淮北 淮南 宣城 黄山 铜陵 亳州 池州 巢湖 滁州
  • 海南
  • 三亚 海口 琼海 文昌 东方
  • 江西
  • 南昌 赣州 上饶 吉安 九江 新余 抚州 宜春 景德镇 萍乡 鹰潭
  • 湖北
  • 武汉 宜昌 襄樊 荆州 恩施 孝感 黄冈 十堰 咸宁 黄石 仙桃 随州 天门 荆门 潜江 鄂州 神农架
  • 山西
  • 太原 大同 运城 长治 晋城 忻州 临汾 吕梁 晋中 阳泉 朔州
  • 辽宁
  • 大连 沈阳 丹东 辽阳 葫芦岛 锦州 朝阳 营口 鞍山 抚顺 阜新 本溪 盘锦 铁岭
  • 黑龙江
  • 齐齐哈尔 哈尔滨 大庆 佳木斯 双鸭山 牡丹江 鸡西 黑河 绥化 鹤岗 伊春 大兴安岭 七台河
  • 内蒙古
  • 赤峰 包头 通辽 呼和浩特 乌海 鄂尔多斯 呼伦贝尔
  • 贵州
  • 贵阳 黔东 黔南 遵义 黔西 毕节 铜仁 安顺 六盘水
  • 甘肃
  • 兰州 天水 庆阳 武威 酒泉 张掖 陇南 白银 定西 平凉 嘉峪关 临夏 金昌 甘南
  • 青海
  • 西宁 海西 海东 海北 果洛 玉树 黄南
  • 新疆
  • 乌鲁木齐 伊犁 昌吉 石河子 哈密
  • 西藏
  • 拉萨 山南 林芝 日喀则
  • 吉林
  • 长春 白山 白城 延边 松原 辽源 通化 四平
  • 宁夏
  • 银川 吴忠 中卫 石嘴山 固原
SiteMap
网站地图
TAG标签
Copyright © 2017-2025 TYWEB.NET 宿迁腾云网络科技有限公司 ALL RIGHTS RESERVED.   苏ICP备17033535号-1

热门搜索

百度 下载 2025 2026 2024 请输入关健词 货源 货货源 虚拟 禅道
  • 客服

    在线客服

  • 电话

    13160355545

  • 微信

精品模板
建站费用
成功案例
联系我们