PHP仿微信发红包领红包效果(2)

# 引入中间状态 ALTER TABLE `red_packet` MODIFY COLUMN `pay_status` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '支付状态:0未支付,1已支付,2等待到账' AFTER `for_id`, ADD COLUMN `pay_type` tinyint(1) NOT NULL DEFAULT 0 COMMENT '支付方式:0未知,1支付宝,2微信,3银联' AFTER `pay_status`, ADD COLUMN `trade_no` varchar(30) NOT NULL DEFAULT '' COMMENT '第三方支付交易号' AFTER `pay_type`; ALTER TABLE `red_packet_log` ADD COLUMN `is_into_account` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否到账:0否,1是' AFTER `is_good`;

用户抢到红包的时候,根据 pay_status 来决定 is_into_account 的值;

同步回调到app端时,调用接口把支付状态 pay_status 变为2;

异步回调到服务端时,则把支付状态 pay_status 变为1,并查出 is_into_account=1 的 red_packet_log 记录进行处理。

但是上面这三步都要对 red_packet 的查询进行 FOR UPDATE 操作,不然会有执行时间和顺序问题,导致部分 red_packet_log 记录未到账 is_into_account=0;另外锁机制还会使得用户抢红包时变得很慢,因为要等锁释放。


改进如下:(全程不 FOR UPDATE)

用户抢到红包的时候,根据 pay_status 来决定 is_into_account 的值;

同步回调到app端时,调用接口把支付状态 pay_status 变为2;

异步回调到服务端时,则把支付状态 pay_status 变为1,并把红包id(red_packet主键)放入MQ;

后台自动脚本,从MQ拿到红包id之后,把该红包 is_into_account=0 的记录进行处理,然后再延迟5秒把红包id再次写入MQ,进行二次处理,确保数据全部到账。

五、红包过期退还

这里就一个自动脚本,根据 red_packet 表的 pay_time 判断是否超过24小时且没领完的钱,退回用户余额。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/aa1dabfa6da6e54a7d465ea1df943481.html