优惠券使用日志必须在订单状态为confirmed或paid时,与优惠券核销操作同事务写入,discount_amount须为实际减免额而非面值,并建coupon_id与order_id联合索引保障查询性能。
优惠券是否被使用,必须在订单状态确认为 confirmed 或 paid 的那一刻落库,不能依赖前端传参或事后补录。PHP 后端在调用 createOrder() 逻辑中,一旦确定优惠券 ID($coupon_id)已核销,就应立即插入日志记录。
order_id、coupon_id、discount_amount(实际减扣金额,不是面值)、used_at(date('Y-m-d H:i:s'))、created_at
INSERT IGNORE 或 ON DUPLICATE KEY UPDATE 处理重复
——优惠券只能被一个订单使用,重复写入本身就是业务异常,应抛出 LogicException 并回滚事务coupons.used_count)处于同一数据库事务中,否则会出现“券扣了但没留痕”以下代码假设你已开启 PDO 的异常模式($pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)),且所有操作都在一个事务内完成:
$pdo->beginTransaction();
try {
// 1. 更新优惠券使用次数
$stmt = $pdo->prepare("UPDATE coupons SET used_count = used_count + 1 WHERE id = ? AND status = 'active' AND remaining > 0");
$stmt->execute([$coupon_id]);
if ($stmt->rowCount() === 0) {
throw new Exception('Coupon not available or already used');
}
// 2. 插入优惠券使用日志
$stmt = $pdo->prepare("INSERT INTO coupon_usage_log (order_id, coupon_id, discount_amount, used_at, created_at) VALUES (?, ?, ?, NOW(), NOW())");
$stmt->execute([$order_id, $coupon_id, $actual_discount]);
// 3. 创建订单主记录(略)
createOrderRecord($pdo, $order_data);
$pdo->commit();} catch (Exception $e) {
$pdo->rollback();
throw $e;
}
日志字段 discount\_amount 必须是实际减免值,不是 coupon\_amount
用户领到一张“满 200 减 50”的券,但订单实付 180 元,此时该券根本无法使用;若订单是 220 元,系统可能只减免了 45 元(因部分商品不参与活动),那么日志里的 discount_amount 必须记 45.00,而不是券面额 50.00。
coupons.amount 字段直接读取coupon_amount 不可信,需服务端重新校验并计算真实减免额线上查某张券用了哪些订单,或查某订单用了哪张券,都是高频操作。如果只对 coupon_id 或 order_id 单独建索引,MySQL 在 WHERE coupon_id = ? + ORDER BY used_at DESC 场景下仍可能触发 filesort。
ALTER TABLE coupon_usage_log ADD INDEX idx_coupon_order (coupon_id, order_id)
(used_at, coupon_id),但优先保障 coupon_id 在前SELECT * FROM coupon_usage_log WHERE coupon_id = 123 在百万级数据下可能秒变慢查询优惠券日志看似简单,真正难的是“一致性”——券扣了、钱少了、日志没写,这种缺口在线上几乎无法追溯。所以核心不是怎么记,而是记的时机、事务边界和字段语义是否和业务规则完全咬合。
# mysql
# php
# 前端
# 后端
# ai
# select
# date
# throw
# catch
# pdo
# table
# 数据库
# 的是
# 用了
# 线上
# 而非
# 都是
# 都在
# 要把
# 少了
# 那一刻
# 在前
相关文章:
C#如何序列化对象为XML XmlSerializer用法
Python多线程使用规范_线程安全解析【教程】
建站主机与虚拟主机有何区别?如何选择最优方案?
个人摄影网站制作流程,摄影爱好者都去什么网站?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
建站主机服务器选购指南:轻量应用与VPS配置解析
学校免费自助建站系统:智能生成+拖拽设计+多端适配
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
青岛网站建设如何选择本地服务器?
黑客如何利用漏洞与弱口令入侵网站服务器?
网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?
网站制作公司广州有几家,广州尚艺美发学校网站是多少?
网站视频怎么制作,哪个网站可以免费收看好莱坞经典大片?
如何规划企业建站流程的关键步骤?
高性价比服务器租赁——企业级配置与24小时运维服务
如何快速搭建虚拟主机网站?新手必看指南
python的本地网站制作,如何创建本地站点?
广州商城建站系统开发成本与周期如何控制?
建站之星如何开启自定义404页面避免用户流失?
如何打造高效商业网站?建站目的决定转化率
css网站制作参考文献有哪些,易聊怎么注册?
北京制作网站的公司,北京铁路集团官方网站?
5种Android数据存储方式汇总
建站之星安装步骤有哪些常见问题?
建站主机解析:虚拟主机配置与服务器选择指南
如何获取PHP WAP自助建站系统源码?
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
建站主机默认首页配置指南:核心功能与访问路径优化
建站三合一如何选?哪家性价比更高?
教育培训网站制作流程,请问edu教育网站的域名怎么申请?
建站之星体验版:智能建站系统+响应式设计,多端适配快速建站
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
大同网页,大同瑞慈医院官网?
Swift中循环语句中的转移语句 break 和 continue
如何快速搭建二级域名独立网站?
名字制作网站免费,所有小说网站的名字?
建站之星安装模板失败:服务器环境不兼容?
如何做网站制作流程,*游戏网站怎么搭建?
小型网站制作HTML,*游戏网站怎么搭建?
小程序网站制作需要准备什么资料,如何制作小程序?
如何彻底删除建站之星生成的Banner?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
javascript中的try catch异常捕获机制用法分析
建站之星在线版空间:自助建站+智能模板一键生成方案
建站主机选虚拟主机还是云服务器更好?
大连网站制作公司哪家好一点,大连买房网站哪个好?
利用JavaScript实现拖拽改变元素大小
建站之星Pro快速搭建教程:模板选择与功能配置指南
陕西网站制作公司有哪些,陕西凌云电器有限公司官网?
*请认真填写需求信息,我们会在24小时内与您取得联系。