201650-修复Mex模块事务嵌套问题.md 3.7 KB

修复Mex模块事务嵌套问题

任务时间

  • 开始时间:2025年06月20日 16:45:00 CST
  • 完成时间:2025年06月20日 16:50:24 CST

问题描述

用户报告农贸市场挂单功能出现错误,通过日志分析发现是事务嵌套问题:

[2025-06-20T16:44:19.050616+08:00] laravel.ERROR: check_tr - transaction level >1 事务嵌套  [] [] []
[2025-06-20T16:44:19.073603+08:00] laravel.ERROR: 创建挂单失败 {"error":"创建订单失败:transaction level > 1"}

问题分析

通过分析调用链发现事务嵌套的原因:

  1. AddHandler 在第56行开启了事务 DB::beginTransaction()
  2. 然后调用 MexOrderService::createSellOrder()
  3. MexOrderService::createSellOrder() 调用 MexOrderLogic::createSellOrder()
  4. MexOrderLogic::createSellOrder() 在第47行又开启了一个事务 DB::transaction()
  5. 最终在 ItemService::freezeItem() 中调用 Helper::check_tr() 检查事务状态
  6. 此时事务级别为2(嵌套事务),触发了 transaction level > 1 错误

解决方案

根据项目规范"逻辑层不能开启事务,需要事务进行事务开启检查",修改Mex模块的事务管理策略:

1. 修改 MexOrderLogic::createSellOrder() 方法

  • 移除方法内部的 DB::transaction() 事务管理
  • 添加事务检查 \UCore\Db\Helper::check_tr() 确保调用者已开启事务
  • 移除事务闭包包装,直接执行业务逻辑

修改前:

return DB::transaction(function () use ($userId, $itemId, $quantity, $price, $currencyType, $totalAmount) {
    try {
        // 业务逻辑
    } catch (\Exception $e) {
        return ['success' => false, 'message' => '创建订单失败:' . $e->getMessage()];
    }
});

修改后:

// 检查事务状态,确保调用者已开启事务
\UCore\Db\Helper::check_tr();

try {
    // 业务逻辑
} catch (\Exception $e) {
    return ['success' => false, 'message' => '创建订单失败:' . $e->getMessage()];
}

2. 修改 MexOrderLogic::createBuyOrder() 方法

  • 添加事务检查 \UCore\Db\Helper::check_tr() 确保调用者已开启事务
  • 保持一致的事务管理策略

验证测试

使用 php artisan debug:reproduce-error 69001992 命令重现错误请求:

修复前:

  • 出现 "check_tr - transaction level >1 事务嵌套" 错误
  • 订单创建失败

修复后:

  • ✅ 没有事务嵌套错误
  • ✅ 订单创建成功(订单ID:78)
  • ✅ 物品冻结成功
  • ✅ 响应消息:"卖出订单创建成功,等待撮合"

技术要点

  1. 事务管理原则:避免嵌套事务,由最外层调用者负责事务管理
  2. 事务检查:使用 \UCore\Db\Helper::check_tr() 确保事务状态正确
  3. 架构规范:逻辑层不开启事务,只进行事务状态检查
  4. 错误处理:移除内层方法的事务管理,让外层统一处理

影响范围

  • 修复了农贸市场挂单功能的事务嵌套错误
  • 优化了Mex模块的事务管理架构
  • 提高了系统的稳定性和可维护性
  • 符合项目架构规范要求

提交信息

修复Mex模块事务嵌套问题

- 移除MexOrderLogic::createSellOrder()方法中的DB::transaction()
- 移除MexOrderLogic::createBuyOrder()方法中的事务管理
- 添加事务检查,确保调用者已开启事务
- 修复农贸市场挂单时的'transaction level > 1'错误
- 所有事务管理现在由调用者(AddHandler)负责

总结

成功修复了Mex模块中的事务嵌套问题,通过重构事务管理策略,确保了系统的稳定性。修复后农贸市场挂单功能正常工作,没有任何错误日志。这次修复遵循了项目的架构规范,将事务管理责任明确分配给了合适的层级。