- 扩大玩家ID随机数位宽降低碰撞概率 - 授信额度变更加 lockForUpdate 防并发下调 - 结算冲正与入账利用唯一索引实现幂等闸门 - 失败登录计数加锁防丢失 - 代理子树查询改用子查询替代全表 pluck - 修复返点默认值百分比单位转换 - 测试中全量 fake 广播事件防 CI 500
This commit is contained in:
@@ -6,6 +6,7 @@ use App\Lottery\ErrorCode;
|
||||
use App\Models\Player;
|
||||
use App\Support\PlayerAuthSource;
|
||||
use Firebase\JWT\JWT;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use App\Exceptions\PlayerAuthenticationException;
|
||||
|
||||
@@ -114,15 +115,31 @@ final class PlayerNativeAuthService
|
||||
{
|
||||
$max = (int) config('lottery.player_auth.native.max_login_attempts', 8);
|
||||
$lockMinutes = (int) config('lottery.player_auth.native.lock_minutes', 15);
|
||||
$count = (int) $player->login_failed_count + 1;
|
||||
|
||||
$updates = ['login_failed_count' => $count];
|
||||
if ($count >= $max) {
|
||||
$updates['login_locked_until'] = now()->addMinutes($lockMinutes);
|
||||
$updates['login_failed_count'] = 0;
|
||||
}
|
||||
// 并发场景下两个错误登录请求都拿到旧 login_failed_count 各自 +1 时,会出现 last-write-wins
|
||||
// 丢失一次失败计数(影响锁定判定准确性)。用 lockForUpdate 取最新计数后再写。
|
||||
\DB::transaction(function () use ($player, $max, $lockMinutes): void {
|
||||
$latest = Player::query()
|
||||
->whereKey((int) $player->id)
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
|
||||
$player->forceFill($updates)->save();
|
||||
if ($latest === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$count = (int) $latest->login_failed_count + 1;
|
||||
|
||||
$updates = ['login_failed_count' => $count];
|
||||
if ($count >= $max) {
|
||||
$updates['login_locked_until'] = now()->addMinutes($lockMinutes);
|
||||
$updates['login_failed_count'] = 0;
|
||||
}
|
||||
|
||||
Player::query()
|
||||
->whereKey((int) $player->id)
|
||||
->update($updates);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user