1.修复同时存在两个游戏对局的错误

This commit is contained in:
2026-05-26 15:45:22 +08:00
parent 38dec9d7a2
commit 8c3f3c4e2c
2 changed files with 29 additions and 13 deletions

View File

@@ -697,7 +697,7 @@ final class GameLiveService
'update_time' => time(), 'update_time' => time(),
]); ]);
if (GameRecordService::isLiveRuntimeEnabled()) { if (GameRecordService::isLiveRuntimeEnabled()) {
GameRecordService::createNextRecordRow(); GameRecordService::createNextRecordRowIfNoActive();
} }
Db::commit(); Db::commit();
} catch (Throwable $e) { } catch (Throwable $e) {

View File

@@ -14,6 +14,7 @@ final class GameRecordService
public const KEY_MANUAL_CREATE = 'period_manual_create_enabled'; public const KEY_MANUAL_CREATE = 'period_manual_create_enabled';
private const ACTIVE_STATUSES = [0, 1, 2, 3]; private const ACTIVE_STATUSES = [0, 1, 2, 3];
private const AUTO_CREATE_LOCK_KEY = 'auto-create-next-record';
public static function getConfigBool(string $key): bool public static function getConfigBool(string $key): bool
{ {
@@ -53,11 +54,8 @@ final class GameRecordService
if (!self::getConfigBool(self::KEY_AUTO_CREATE)) { if (!self::getConfigBool(self::KEY_AUTO_CREATE)) {
return; return;
} }
if (self::hasActiveRecord()) {
return;
}
try { try {
self::createNextRecordRow(); self::createNextRecordRowIfNoActive();
} catch (Throwable) { } catch (Throwable) {
} }
} }
@@ -84,10 +82,7 @@ final class GameRecordService
if (!self::getConfigBool(self::KEY_AUTO_CREATE)) { if (!self::getConfigBool(self::KEY_AUTO_CREATE)) {
return null; return null;
} }
if (self::hasActiveRecord()) { return self::createNextRecordRowIfNoActive();
return null;
}
return self::createNextRecordRow();
} }
/** /**
@@ -111,11 +106,8 @@ final class GameRecordService
if (!self::getConfigBool(self::KEY_AUTO_CREATE)) { if (!self::getConfigBool(self::KEY_AUTO_CREATE)) {
return; return;
} }
if (self::hasActiveRecord()) {
return;
}
try { try {
self::createNextRecordRow(); self::createNextRecordRowIfNoActive();
} catch (Throwable) { } catch (Throwable) {
} }
} }
@@ -132,6 +124,27 @@ final class GameRecordService
*/ */
public static function createNextRecordRow(): string public static function createNextRecordRow(): string
{ {
$created = self::createNextRecordRowIfNoActive();
if ($created === null) {
throw new \RuntimeException((string) __('There is an unfinished round; cannot create a new one'));
}
return $created;
}
/**
* 幂等插入下一期:有进行中局则不插入,返回 null。
*/
public static function createNextRecordRowIfNoActive(): ?string
{
$lock = GameHotDataLock::tryAcquireWithWait(GameHotDataLock::TYPE_GAME_RECORD, self::AUTO_CREATE_LOCK_KEY, 1500);
if (!$lock['acquired']) {
return null;
}
try {
if (self::hasActiveRecord()) {
return null;
}
$periodNo = self::generatePeriodNo(); $periodNo = self::generatePeriodNo();
$now = time(); $now = time();
Db::name('game_record')->insert([ Db::name('game_record')->insert([
@@ -145,6 +158,9 @@ final class GameRecordService
]); ]);
GameHotDataCoordinator::afterGameRecordCommitted(null); GameHotDataCoordinator::afterGameRecordCommitted(null);
return $periodNo; return $periodNo;
} finally {
GameHotDataLock::release(GameHotDataLock::TYPE_GAME_RECORD, self::AUTO_CREATE_LOCK_KEY, $lock['token'], $lock['redis_lock']);
}
} }
private static function generatePeriodNo(): string private static function generatePeriodNo(): string