·
编程代码 ·
252634
php 乐观锁与事务扣减余额仅成功扣除一次的问题分析
在关于 php 使用乐观锁加事务扣除余额的问题中,多次请求同时扣款的情况下,仅成功扣除一次余额的现象是由以下原因造成的:
错误的事务范围
在第一个代码示例中,事务中仅包含修改用户余额的操作,而查询用户余额和计算订单价格等其他操作并没有包含在事务中。这使得查询到用户余额与实际数据库中余额的时间点不同,从而导致乐观锁失效。
错误的乐观锁使用
开发者声称采用了乐观锁方案,但在实际代码中并没有正确实现。find() 查询会触发一次额外的数据库查询,这使得乐观锁条件在后续的 save() 操作前无效。
不必要的 db::commit() 调用
db::transaction() 启动的事务会在内部自动调用 commit(),因此不需要手动调用。
修复建议
为了解决这些问题,可以采用以下修复建议:
- 将所有与扣款相关的操作(包括查询余额、计算订单价格和保存修改)都包含在事务中。
- 正确实现乐观锁,在 save() 之前检查用户余额是否与事务开始时的余额一致。
- 去除不必要的 db::commit() 调用。
修复后的代码示例如下:
public function userbuy()
{
$user = $this->getUser(); //从数据库获取购买商品的用户信息
$oldMoney = $user['balance']; //得到用户旧余额
$orderOffer = $this->getOrderMoney($orderId); //获取次订单价格
if ($oldMoney error('账户余额不足');
//开启数据库事务
Db::transaction(function () use ($user, $orderId, $newMoney) {
$newUser = SmsUser::where(['id' => $user['id'], 'balance' => $oldMoney])->first();
if (!$newUser) $this->error('用户不存在');
$newMoney = $oldMoney - $orderOffer['price'];
$newUser->balance = $newMoney;
//创建订单 code
//扣除库存 code
//创建用户余额变动记录 code
}); //事务会在代码块末尾自动提交/回滚
}
以上就是PHP乐观锁扣款失败只扣一次余额的原因是什么?的详细内容,更多请关注昆居客【www.kunjuke.com】。
7 月 3 日消息,Valve 现已向预览 / Beta 测试通道推送了新版 Steam Deck 客户端更新,本次更新主要修复了多项功能问题,恢复了分辨率设置的完整选项。通用更新恢复了“最高游戏分辨率”下拉菜单中的完整选项,所有选项可在“更多选项”子菜单中找到远程游玩修复了离线设备仍被显示为可流式传输的错误问题SteamRT3 Beta修复了部分游戏无法启动的故障本次更新仅面向 Steam De...
7 月 1 日消息,6 月 29 日,已获受理的商业火箭公司中科宇航更新招股说明书。中科宇航在更新的招股书中提到,预计随着未来 5 年至 10 年我国巨型低轨卫星星座计划的逐步推进,以及导航增强及遥感应用的快速发展,我国商业运载火箭市场将进入一个快速发展周期,公司亦将持续投入研发,保持技术先进性。预计公司未来收入将呈现快速增长,公司管理层基于产业政策、市场空间、产品研发和生产等因素,预计在乐观和中...
闪传连接失败主因是网络权限未开、Wi-Fi直连受阻或系统拦截;需开启WLAN状态/位置/附近设备权限,确认同局域网并关闭AP隔离,退出App后重置飞行模式,再严格按“一键换机”流程配对。 闪传连接失败时,手机之间无法建立直连通道,传输任务卡在“正在连接”或直接报错,多数情况并非软件崩溃,而是网络权限、系统设置或物理连接环节出了偏差。 检查双方设备的网络状态与权限 打开两部手机的「设置」→「无线和网...
Nginx健康检查失败导致502或超时,需先查error.log确认upstream错误,再用curl/telnet验证上游可达性,接着核对health_check配置与后端响应是否匹配,最后可临时注释health_check验证问题根因。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ 当Nginx作为反向代理进行负载均衡时,上游服务器健康...
Qoder连接GitHub失败需按四步修复:先验证网络连通性并清除错误代理;再手动配置hosts绑定GitHub权威IP;然后绑定正确远程仓库并启用自动提交;最后清除Qoder Git缓存并重启。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ Qoder连接GitHub失败会导致代码无法拉取、提交不生效、协作编辑中断,常见于刚配置完Git插...
胖乖生活App查余额有三种方法:一、通过【钱包】入口,点击底部【钱包】→顶部【钱包余额】;二、从【我的】→【余额】;三、在【我的】→【小票】页底部查看“本账户当前余额”。 如果您在使用胖乖生活App时需要确认当前可用资金,但无法快速定位余额显示位置,则可能是由于界面入口不熟悉或版本更新导致路径变化。以下是查询个人账户余额的具体操作步骤: 一、通过【钱包】入口查看余额 该方式适用于最新版胖乖生活Ap...
iPhone App Store下载失败可按五步修复:一、强制切换App Store五个底部标签各两次以刷新缓存;二、还原网络设置并手动配置DNS为8.8.8.8和114.114.114.114;三、确保可用空间超3GB、卸载未用App,并通过开关“自动设置”校准系统时间;四、退出Apple ID后重启设备,重新登录并验证账户状态;五、使用爱思助手PC端直装IPA包绕过App Store限制。 如...
盒马礼品卡可通过APP绑定、门店直接使用或APP内购买三种方式操作:实物卡需输入卡号密码或扫码绑定;电子卡可保存图片扫码或从订单页绑定;APP内可购买新卡并自动添加至账户;门店支持POS机核销或混合支付;所有卡片余额及有效期可在“我的余额”中查看管理。 如果您已获得盒马礼品卡但尚未使用,或希望为盒马账户充值以备消费,则需完成绑定或充值操作。以下是具体可行的操作路径: 一、绑定实物礼品卡 实物礼品卡...