新需求-后台优化-盲盒转盘超抽问题解决

This commit is contained in:
2025-10-21 09:52:27 +08:00
parent 6cca013d61
commit 396dfeaa07

View File

@@ -37,8 +37,6 @@ class BlindBoxTurntableGiftDrawWorld extends Model
public function draw_gift($gift_bag_id, $user_id, $gift_user_ids, $num = 1, $room_id = 0, $heart_id = 0,$auction_id = 0) public function draw_gift($gift_bag_id, $user_id, $gift_user_ids, $num = 1, $room_id = 0, $heart_id = 0,$auction_id = 0)
{ {
// 最大重试次数 // 最大重试次数
$maxRetries = 3;
for ($attempt = 0; $attempt < $maxRetries; $attempt++) {
try { try {
// 1. 验证参数并提前处理错误 // 1. 验证参数并提前处理错误
$validationResult = $this->validateDrawParameters($gift_bag_id, $user_id, $gift_user_ids); $validationResult = $this->validateDrawParameters($gift_bag_id, $user_id, $gift_user_ids);
@@ -75,6 +73,33 @@ class BlindBoxTurntableGiftDrawWorld extends Model
$this->recordDrawErrorToRedis($expectedCount, count($precomputedResults), $room_id, $user_id, $gift_bag_id, $num, $gift_user_ids, $precomputedResults); $this->recordDrawErrorToRedis($expectedCount, count($precomputedResults), $room_id, $user_id, $gift_bag_id, $num, $gift_user_ids, $precomputedResults);
return ['code' => 0, 'msg' => '网络加载失败,请重试!', 'data' => null]; return ['code' => 0, 'msg' => '网络加载失败,请重试!', 'data' => null];
} }
foreach ($precomputedResults as $result) {
$key = $result['gift_user_id'] . '_' . $result['gift_bag_detail']['foreign_id'];
if (!isset($giftUserCountsJianCha[$key])) {
$giftUserCountsJianCha[$key] = [
'gift_user_id' => $result['gift_user_id'],
'gift_id' => $result['gift_bag_detail']['foreign_id'],
'count' => 0,
'gift_price' => $result['gift']['gift_price'],
'quantity' => $result['gift_bag_detail']['quantity'],
];
}
$giftUserCountsJianCha[$key]['count']++;
if($giftUserCountsJianCha[$key]['count'] > $result['gift_bag_detail']['quantity']){
// 记录错误到Redis
// 使用正确的Redis方法存储数据
$key = 'blind_box_draw_world_errors_' . date('Y-m-d-H-i-s');
$errorData = [
'gift_bag_id' => $gift_bag_id,
'user_id' => $user_id,
'gift_user_ids' => $gift_user_ids,
'num' => $num,
'giftUserCountsJianCha' => $giftUserCountsJianCha,
];
$this->redis->setex($key, 86400 * 7, "礼物数量超出限制 ".json_encode($errorData));
return ['code' => 0, 'msg' => '网络加载失败,请重试!', 'data' => null];
}
}
// 4. 执行抽奖事务(核心操作) // 4. 执行抽奖事务(核心操作)
$transactionResult = $this->executeDrawTransaction( $transactionResult = $this->executeDrawTransaction(
$bag_data, $bag_data,
@@ -121,16 +146,9 @@ class BlindBoxTurntableGiftDrawWorld extends Model
if ($this->redis) { if ($this->redis) {
$this->redis->setex($key, 86400 * 7, $e->getMessage() . ' ' . json_encode($errorData)); $this->redis->setex($key, 86400 * 7, $e->getMessage() . ' ' . json_encode($errorData));
} }
// 如果是死锁且还有重试机会
if (strpos($e->getMessage(), 'Deadlock') !== false && $attempt < $maxRetries - 1) {
// 随机延迟后重试
usleep(rand(50000, 200000)); // 50-200ms
continue;
}
return ['code' => 0, 'msg' => "网络加载失败,请重试!", 'data' => null]; return ['code' => 0, 'msg' => "网络加载失败,请重试!", 'data' => null];
} }
} }
}
/** /**
* 验证抽奖参数 * 验证抽奖参数
*/ */
@@ -495,8 +513,6 @@ class BlindBoxTurntableGiftDrawWorld extends Model
$bagGiftPrice = $bag_data['gift_price'] * $num * $gift_user_num; $bagGiftPrice = $bag_data['gift_price'] * $num * $gift_user_num;
// 增加重试机制 // 增加重试机制
$maxRetries = 3;
for ($retry = 0; $retry < $maxRetries; $retry++) {
try { try {
db::startTrans(); db::startTrans();
// 按照固定顺序处理事务步骤 // 按照固定顺序处理事务步骤
@@ -544,17 +560,9 @@ class BlindBoxTurntableGiftDrawWorld extends Model
]; ];
} catch (\Exception $e) { } catch (\Exception $e) {
db::rollback(); db::rollback();
// 检查是否是死锁错误
if (strpos($e->getMessage(), 'Deadlock') !== false && $retry < $maxRetries - 1) {
// 等待随机时间后重试
usleep(rand(10000, 100000)); // 10-100ms
continue;
}
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null]; return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
} }
} }
return ['code' => 0, 'msg' => '操作超时,请重试', 'data' => null];
}
/** /**
* 批量更新礼物库存 * 批量更新礼物库存
@@ -692,7 +700,6 @@ class BlindBoxTurntableGiftDrawWorld extends Model
} }
$giftUserCounts[$key]['count']++; $giftUserCounts[$key]['count']++;
} }
// 批量插入 // 批量插入
$batchInsertData = []; $batchInsertData = [];
foreach ($giftUserCounts as $userGift) { foreach ($giftUserCounts as $userGift) {