|
|
@@ -0,0 +1,103 @@
|
|
|
+# 修复消耗组服务事务嵌套问题
|
|
|
+
|
|
|
+## 任务时间
|
|
|
+- 开始时间:2025年06月06日 15:10:35 CST
|
|
|
+- 完成时间:2025年06月06日 15:15:15 CST
|
|
|
+
|
|
|
+## 问题描述
|
|
|
+用户报告 `request_1749193224473` 请求出现错误,通过日志分析发现是事务嵌套问题:
|
|
|
+```
|
|
|
+[2025-06-06T15:10:47.099459+08:00] laravel.ERROR: check_tr - transaction level >1 事务嵌套 [] [] []
|
|
|
+[2025-06-06T15:10:47.115180+08:00] laravel.ERROR: 执行消耗失败 {"user_id":10006,"consume_group":31,"source":"开启宝箱","source_id":27,"error":"transaction level > 1"} []
|
|
|
+```
|
|
|
+
|
|
|
+## 问题分析
|
|
|
+通过分析调用链发现事务嵌套的原因:
|
|
|
+1. `OpenboxHandler` 在第57行开启了事务 `DB::beginTransaction()`
|
|
|
+2. 然后调用 `ChestService::openChest()`
|
|
|
+3. `ChestService::openChest()` 调用 `ConsumeService::executeConsume()`
|
|
|
+4. `ConsumeService::executeConsume()` 在第127行又开启了一个事务 `DB::beginTransaction()`
|
|
|
+5. 最终在 `ItemService::consumeItem()` 中调用 `Helper::check_tr()` 检查事务状态
|
|
|
+6. 此时事务级别为2(嵌套事务),触发了 `transaction level > 1` 错误
|
|
|
+
|
|
|
+## 解决方案
|
|
|
+修改消耗组服务的事务管理策略,让调用者负责事务管理:
|
|
|
+
|
|
|
+### 1. 修改 `ConsumeService::executeConsume()` 方法
|
|
|
+- 移除方法内部的事务管理(`DB::beginTransaction()` 和 `DB::commit()`)
|
|
|
+- 添加事务检查 `\UCore\Db\Helper::check_tr()` 确保调用者已开启事务
|
|
|
+- 移除异常处理中的事务回滚逻辑
|
|
|
+
|
|
|
+### 2. 修改 `executeCurrencyConsume()` 方法
|
|
|
+- 移除内部事务管理
|
|
|
+- 添加事务检查
|
|
|
+- 移除异常处理中的事务回滚逻辑
|
|
|
+
|
|
|
+### 3. 修改 `executeFundConfigsConsume()` 方法
|
|
|
+- 移除内部事务管理
|
|
|
+- 添加事务检查
|
|
|
+- 移除异常处理中的事务回滚逻辑
|
|
|
+
|
|
|
+### 4. 移除不再使用的DB导入
|
|
|
+- 从 `use` 语句中移除 `Illuminate\Support\Facades\DB`
|
|
|
+
|
|
|
+## 修改的文件
|
|
|
+- `app/Module/Game/Services/ConsumeService.php`
|
|
|
+
|
|
|
+## 验证结果
|
|
|
+使用验证命令测试修复效果:
|
|
|
+```bash
|
|
|
+php artisan debug:reproduce-error request_1749193224473
|
|
|
+```
|
|
|
+
|
|
|
+修复前:
|
|
|
+```
|
|
|
+[2025-06-06T15:10:47.099459+08:00] laravel.ERROR: check_tr - transaction level >1 事务嵌套
|
|
|
+```
|
|
|
+
|
|
|
+修复后:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "runUnid": "6842957cb4235",
|
|
|
+ "runMs": "6093",
|
|
|
+ "code": "OK",
|
|
|
+ "callpath": "Item-Openbox",
|
|
|
+ "deduct": {
|
|
|
+ "items": [
|
|
|
+ {"itemId": "2", "quantity": "500"},
|
|
|
+ {"itemId": "3", "quantity": "500"},
|
|
|
+ {"itemId": "27", "quantity": "1"}
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "reward": {
|
|
|
+ "items": [
|
|
|
+ {"itemId": "2", "quantity": "1622"}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 技术要点
|
|
|
+1. **事务管理原则**:避免嵌套事务,由最外层调用者负责事务管理
|
|
|
+2. **事务检查**:使用 `\UCore\Db\Helper::check_tr()` 确保事务状态正确
|
|
|
+3. **错误处理**:移除内层方法的事务回滚,让外层统一处理
|
|
|
+4. **代码清理**:移除不再使用的导入语句
|
|
|
+
|
|
|
+## 影响范围
|
|
|
+- 修复了宝箱开启功能的事务嵌套错误
|
|
|
+- 优化了消耗组服务的事务管理架构
|
|
|
+- 提高了系统的稳定性和可维护性
|
|
|
+
|
|
|
+## 提交信息
|
|
|
+```
|
|
|
+修复消耗组服务事务嵌套问题
|
|
|
+
|
|
|
+- 移除ConsumeService::executeConsume()方法中的事务管理
|
|
|
+- 移除executeCurrencyConsume()和executeFundConfigsConsume()方法中的事务管理
|
|
|
+- 添加事务检查,确保调用者已开启事务
|
|
|
+- 修复宝箱开启时的'transaction level > 1'错误
|
|
|
+- 所有事务管理现在由调用者(如ChestService::openChest)负责
|
|
|
+```
|
|
|
+
|
|
|
+## 总结
|
|
|
+成功修复了消耗组服务中的事务嵌套问题,通过重构事务管理策略,确保了系统的稳定性。修复后宝箱开启功能正常工作,没有任何错误日志。
|