|
@@ -348,15 +348,24 @@ class ItemFreeze
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 从用户可用物品中扣除差额,补足到冻结堆
|
|
|
|
|
|
|
+ // 从用户可用物品中扣除差额,补足到冻结堆(使用锁定避免并发问题)
|
|
|
$availableItems = ItemUser::where('user_id', $frozenItem->user_id)
|
|
$availableItems = ItemUser::where('user_id', $frozenItem->user_id)
|
|
|
->where('item_id', $frozenItem->item_id)
|
|
->where('item_id', $frozenItem->item_id)
|
|
|
->where('is_frozen', false)
|
|
->where('is_frozen', false)
|
|
|
->whereNull('instance_id')
|
|
->whereNull('instance_id')
|
|
|
->where('quantity', '>', 0)
|
|
->where('quantity', '>', 0)
|
|
|
->orderBy('expire_at')
|
|
->orderBy('expire_at')
|
|
|
|
|
+ ->lockForUpdate() // 锁定记录,避免并发修改
|
|
|
->get();
|
|
->get();
|
|
|
|
|
|
|
|
|
|
+ // 重新验证可用数量(锁定后可能已变化)
|
|
|
|
|
+ $actualAvailableQuantity = $availableItems->sum('quantity');
|
|
|
|
|
+ if ($actualAvailableQuantity < $shortageQuantity) {
|
|
|
|
|
+ throw new Exception(
|
|
|
|
|
+ "解冻失败:需要补足 {$shortageQuantity},但锁定后用户可用数量只有 {$actualAvailableQuantity}"
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$remainingShortage = $shortageQuantity;
|
|
$remainingShortage = $shortageQuantity;
|
|
|
$transferDetails = []; // 记录转移详情
|
|
$transferDetails = []; // 记录转移详情
|
|
|
|
|
|
|
@@ -830,15 +839,33 @@ class ItemFreeze
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 从用户可用物品中补足全部数量
|
|
|
|
|
|
|
+ // 从用户可用物品中补足全部数量(使用锁定避免并发问题)
|
|
|
$availableItems = ItemUser::where('user_id', $frozenItem->user_id)
|
|
$availableItems = ItemUser::where('user_id', $frozenItem->user_id)
|
|
|
->where('item_id', $frozenItem->item_id)
|
|
->where('item_id', $frozenItem->item_id)
|
|
|
->where('is_frozen', false)
|
|
->where('is_frozen', false)
|
|
|
->whereNull('instance_id')
|
|
->whereNull('instance_id')
|
|
|
->where('quantity', '>', 0)
|
|
->where('quantity', '>', 0)
|
|
|
->orderBy('expire_at')
|
|
->orderBy('expire_at')
|
|
|
|
|
+ ->lockForUpdate() // 锁定记录,避免并发修改
|
|
|
->get();
|
|
->get();
|
|
|
|
|
|
|
|
|
|
+ // 重新验证可用数量(锁定后可能已变化)
|
|
|
|
|
+ $actualAvailableQuantity = $availableItems->sum('quantity');
|
|
|
|
|
+ if ($actualAvailableQuantity < $originalFrozenQuantity) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'success' => false,
|
|
|
|
|
+ 'status' => 'insufficient_available_after_lock',
|
|
|
|
|
+ 'message' => "冻结物品已被完全消耗,锁定后用户可用数量不足以补足原始冻结数量",
|
|
|
|
|
+ 'user_id' => $frozenItem->user_id,
|
|
|
|
|
+ 'item_id' => $frozenItem->item_id,
|
|
|
|
|
+ 'instance_id' => $frozenItem->instance_id,
|
|
|
|
|
+ 'unfrozen_quantity' => 0,
|
|
|
|
|
+ 'original_frozen_quantity' => $originalFrozenQuantity,
|
|
|
|
|
+ 'available_quantity' => $actualAvailableQuantity,
|
|
|
|
|
+ 'shortage_quantity' => $originalFrozenQuantity - $actualAvailableQuantity,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$remainingQuantity = $originalFrozenQuantity;
|
|
$remainingQuantity = $originalFrozenQuantity;
|
|
|
$transferDetails = []; // 记录转移详情
|
|
$transferDetails = []; // 记录转移详情
|
|
|
|
|
|
|
@@ -957,15 +984,34 @@ class ItemFreeze
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 从用户可用物品中扣除差额,补足到冻结堆
|
|
|
|
|
|
|
+ // 从用户可用物品中扣除差额,补足到冻结堆(使用锁定避免并发问题)
|
|
|
$availableItems = ItemUser::where('user_id', $frozenItem->user_id)
|
|
$availableItems = ItemUser::where('user_id', $frozenItem->user_id)
|
|
|
->where('item_id', $frozenItem->item_id)
|
|
->where('item_id', $frozenItem->item_id)
|
|
|
->where('is_frozen', false)
|
|
->where('is_frozen', false)
|
|
|
->whereNull('instance_id')
|
|
->whereNull('instance_id')
|
|
|
->where('quantity', '>', 0)
|
|
->where('quantity', '>', 0)
|
|
|
->orderBy('expire_at')
|
|
->orderBy('expire_at')
|
|
|
|
|
+ ->lockForUpdate() // 锁定记录,避免并发修改
|
|
|
->get();
|
|
->get();
|
|
|
|
|
|
|
|
|
|
+ // 重新验证可用数量(锁定后可能已变化)
|
|
|
|
|
+ $actualAvailableQuantity = $availableItems->sum('quantity');
|
|
|
|
|
+ if ($actualAvailableQuantity < $shortageQuantity) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'success' => false,
|
|
|
|
|
+ 'status' => 'insufficient_available_after_lock',
|
|
|
|
|
+ 'message' => "解冻失败:需要补足 {$shortageQuantity},但锁定后用户可用数量只有 {$actualAvailableQuantity}",
|
|
|
|
|
+ 'user_id' => $frozenItem->user_id,
|
|
|
|
|
+ 'item_id' => $frozenItem->item_id,
|
|
|
|
|
+ 'instance_id' => $frozenItem->instance_id,
|
|
|
|
|
+ 'unfrozen_quantity' => 0,
|
|
|
|
|
+ 'original_frozen_quantity' => $originalFrozenQuantity,
|
|
|
|
|
+ 'current_frozen_quantity' => $currentQuantity,
|
|
|
|
|
+ 'shortage_quantity' => $shortageQuantity,
|
|
|
|
|
+ 'available_quantity' => $actualAvailableQuantity,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$remainingShortage = $shortageQuantity;
|
|
$remainingShortage = $shortageQuantity;
|
|
|
$transferDetails = []; // 记录转移详情
|
|
$transferDetails = []; // 记录转移详情
|
|
|
|
|
|