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

@@ -14,6 +14,7 @@ final class GameRecordService
public const KEY_MANUAL_CREATE = 'period_manual_create_enabled';
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
{
@@ -53,11 +54,8 @@ final class GameRecordService
if (!self::getConfigBool(self::KEY_AUTO_CREATE)) {
return;
}
if (self::hasActiveRecord()) {
return;
}
try {
self::createNextRecordRow();
self::createNextRecordRowIfNoActive();
} catch (Throwable) {
}
}
@@ -84,10 +82,7 @@ final class GameRecordService
if (!self::getConfigBool(self::KEY_AUTO_CREATE)) {
return null;
}
if (self::hasActiveRecord()) {
return null;
}
return self::createNextRecordRow();
return self::createNextRecordRowIfNoActive();
}
/**
@@ -111,11 +106,8 @@ final class GameRecordService
if (!self::getConfigBool(self::KEY_AUTO_CREATE)) {
return;
}
if (self::hasActiveRecord()) {
return;
}
try {
self::createNextRecordRow();
self::createNextRecordRowIfNoActive();
} catch (Throwable) {
}
}
@@ -132,6 +124,27 @@ final class GameRecordService
*/
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();
$now = time();
Db::name('game_record')->insert([
@@ -145,6 +158,9 @@ final class GameRecordService
]);
GameHotDataCoordinator::afterGameRecordCommitted(null);
return $periodNo;
} finally {
GameHotDataLock::release(GameHotDataLock::TYPE_GAME_RECORD, self::AUTO_CREATE_LOCK_KEY, $lock['token'], $lock['redis_lock']);
}
}
private static function generatePeriodNo(): string