返回顶部
首页 > 资讯 > 精选 >利用swoole实现订单延时
  • 332
分享到

利用swoole实现订单延时

2023-06-20 18:06:49 332人浏览 泡泡鱼
摘要

本篇内容介绍了“利用swoole实现订单延时”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、业务场景:当客户下单在指定的时间内如果没有付款

本篇内容介绍了“利用swoole实现订单延时”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

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

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

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

如下图,图解:

第一次下完单产品ID1库存从20减到了10,产品ID2库存从40减到了20;2、第二次下完单产品ID的库存为0了,产品ID2的库存也为0了,

第三次下单时,程序提示Out of stock;

过了10秒钟(每个订单下单后往后推10秒),客户两次下单,由于没有付款(csdn_order表的order_status为1),产品1和产品2的库存被还原了(csdn_order表的order_status变为0),客户又可以继续下单了

所需要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,这里对订单生成,同时扣除库存的一系列操作

<?phprequire("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

<?phprequire("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);}?>

“利用swoole实现订单延时”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 利用swoole实现订单延时

本文链接: https://www.lsjlt.com/news/299159.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 利用swoole实现订单延时
    本篇内容介绍了“利用swoole实现订单延时”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、业务场景:当客户下单在指定的时间内如果没有付款...
    99+
    2023-06-20
  • Android实现订单倒计时功能
    先上效果图 1.activity_main.xml <?xml version="1.0" encoding="utf-8"?> <R...
    99+
    2022-06-06
    倒计时 Android
  • 利用Redis实现订单30分钟自动取消
    目录业务场景实现思路开启 Redis key 过期提醒引入依赖相关配置redis 过期监听真的好么?实现关闭订单的方法业务场景 我们以订单功能为例说明下: 生成订单后一段时间不支付订单会自动关闭。最简单的想法是设置定时任...
    99+
    2022-06-27
    Redis订单自动取消 Redis订单30分钟自动取消
  • redis实现队列的阻塞、延时、发布和订阅
    目录普通队列阻塞队列发布订阅模式延时队列和优先级队列应用场景Redis不仅可作为缓存服务器,还可以用作消息队列。它的列表类型天生支持用作消息队列。如下图所示: 由于Redis的列表...
    99+
    2024-04-02
  • redis怎么实现队列阻塞、延时、发布和订阅
    这篇“redis怎么实现队列阻塞、延时、发布和订阅”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“redis怎么实现队列阻塞、...
    99+
    2023-07-02
  • C#使用Lazy<T>实现对客户订单的延迟加载
    "延迟加载"是指在需要的时候再加载数据。比如获得一个Customer信息,并不会把该Customer的Orders信息一下加载出来,当需要显示Orders的时候再...
    99+
    2024-04-02
  • Android利用SurfaceView实现简单计时器
    自学了android有几个月了,跟着网上的节奏,应该早点写些博客来提高自己的水准的。但苦于技术水准始终不自信(也是不过关的结果吧),就一直只是将自己学习过程中的问题和重要的知识...
    99+
    2022-06-06
    surfaceview 计时器 Android
  • redis如何实现队列的阻塞、延时、发布和订阅
    这篇文章主要介绍了redis如何实现队列的阻塞、延时、发布和订阅的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇redis如何实现队列的阻塞、延时、发布和订阅文章都会有所收获,下...
    99+
    2024-04-02
  • 如何利用rabbitMq的死信队列实现延时消息
    目录前言mq基本的消息模型mq死信队列的消息模型maven依赖配置普通队列和死信队列死信队列消费者发送消息测试测试成功总结前言 使用mq自带的死信去实现延时消息要注意一个坑点,就是m...
    99+
    2023-01-28
    rabbitMq死信队列 rabbitMq延时消息 rabbitMq延时队列
  • redis订单超时取消功能怎么实现
    要实现Redis订单超时取消功能,可以使用Redis的Sorted Set和定时任务结合实现。1. 在Redis中创建一个Sorte...
    99+
    2023-09-06
    redis
  • 利用JavaScript实现简单的网页时钟
    目录一、效果展示二、使用的技术三、日期对象1.指定时间2.获取目前时间三、源代码前言: 今天带大家使用JavaScript定制一款网页时钟 一、效果展示 二、使用的技术 主要使用了...
    99+
    2024-04-02
  • swoole如何实现定时任务
    这篇文章主要为大家展示了“swoole如何实现定时任务”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“swoole如何实现定时任务”这篇文章吧。方法:1、利用“swoole_timer_after...
    99+
    2023-06-29
  • 如何利用C++实现一个简单的飞机订票系统?
    如何利用C++实现一个简单的飞机订票系统?随着空中交通的发展和人们对舒适旅行的需求增加,飞机订票系统变得越来越重要。在这篇文章中,我们将学习如何利用C++编程语言来实现一个简单的飞机订票系统。这个系统将允许用户查询航班信息、选择座位、预订和...
    99+
    2023-11-02
    C++ 飞机 订票系统
  • java怎么实现延时
    java实现延时的方法:使用Timer类Timer类负责计划任务的功能,也即指定的时间开始执行某个任务。Timer类的作用只是用于设置计划任务。Timer类的schedule方法可以按照时间计划执行程序。 public static vo...
    99+
    2018-07-15
    java
  • 利用Python实现电影订票系统
    目录一、效果展示二、整体结构图 三、代码分解3.1infos.py 3.2seat_book.py3.3film_selector.py3.4main....
    99+
    2024-04-02
  • celery异步定时任务怎么实现订单定时回滚
    这篇文章主要介绍“celery异步定时任务怎么实现订单定时回滚”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“celery异步定时任务怎么实现订单定时回滚”文章能帮助大家解决问题。订单回滚用celer...
    99+
    2023-06-30
  • Swoole中怎么实现定时任务
    这篇文章主要介绍“Swoole中怎么实现定时任务”,在日常操作中,相信很多人在Swoole中怎么实现定时任务问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Swoole中怎么实现定时任务”的疑惑有所帮助!接下来...
    99+
    2023-07-05
  • PHP Websocket开发指南,实现实时订单处理功能
    PHP Websocket开发指南,实现实时订单处理功能Websocket是一种在Web应用程序和服务器之间进行实时双向通信的协议。相比于传统的HTTP请求,WebSocket能够更高效地建立持久连接,以实现实时的数据传输。在本文中,我将向...
    99+
    2023-12-09
    websocket 关键词:PHP 实时订单处理
  • laravel中怎么实现订单
    本篇内容介绍了“laravel中怎么实现订单”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是订单在购物、餐饮、快递等领域,订单是非常常见...
    99+
    2023-07-06
  • 如何利用C++实现一个简单的火车票订购系统?
    随着人们工作和生活方式的变化,越来越多的人选择乘坐火车出行。因此,实现一个简单的火车票订购系统可以方便用户预订车票,同时也可以提高工作效率,减少人力投入。本文将介绍如何使用C++实现一个简单的火车票订购系统,以方便读者学习和实践。一、需求分...
    99+
    2023-11-03
    C++ 火车票 订购系统
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作