1.增加互斥锁:保证缓存和数据库数据一致性
2.增加消费队列,保证mysql数据的正常保存
This commit is contained in:
@@ -5,6 +5,8 @@ declare(strict_types=1);
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\library\game\StreakWinReward;
|
||||
use app\common\service\GameHotDataCoordinator;
|
||||
use app\common\service\GameHotDataLock;
|
||||
use support\think\Db;
|
||||
use Throwable;
|
||||
use Webman\Push\Api;
|
||||
@@ -253,13 +255,22 @@ final class GameLiveService
|
||||
return ['ok' => false, 'msg' => __('This period has ended; please refresh the page')];
|
||||
}
|
||||
|
||||
self::ensureAiLocked((int) $record['id']);
|
||||
Db::name('game_record')->where('id', (int) $record['id'])->update([
|
||||
'pending_draw_number' => $manualNumber,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
GameHotDataRedis::gameRecordForget((int) $record['id']);
|
||||
self::publishSnapshot(null);
|
||||
$rid = (int) $record['id'];
|
||||
$lock = GameHotDataLock::tryAcquireWithWait(GameHotDataLock::TYPE_GAME_RECORD, (string) $rid, 1200);
|
||||
if (!$lock['acquired']) {
|
||||
return ['ok' => false, 'msg' => __('Another operation is in progress for this period; please try again later')];
|
||||
}
|
||||
try {
|
||||
self::ensureAiLocked($rid);
|
||||
Db::name('game_record')->where('id', $rid)->update([
|
||||
'pending_draw_number' => $manualNumber,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
GameHotDataCoordinator::afterGameRecordCommitted($rid);
|
||||
self::publishSnapshot(null);
|
||||
} finally {
|
||||
GameHotDataLock::release(GameHotDataLock::TYPE_GAME_RECORD, (string) $rid, $lock['token'], $lock['redis_lock']);
|
||||
}
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
@@ -289,8 +300,14 @@ final class GameLiveService
|
||||
return ['ok' => false, 'msg' => __('Period countdown has not ended; cannot draw yet')];
|
||||
}
|
||||
|
||||
self::ensureAiLocked((int) $record['id']);
|
||||
$record = self::reloadRecord((int) $record['id']);
|
||||
$rid = (int) $record['id'];
|
||||
$lock = GameHotDataLock::tryAcquireWithWait(GameHotDataLock::TYPE_GAME_RECORD, (string) $rid, 2000);
|
||||
if (!$lock['acquired']) {
|
||||
return ['ok' => false, 'msg' => __('Another operation is in progress for this period; please try again later')];
|
||||
}
|
||||
try {
|
||||
self::ensureAiLocked($rid);
|
||||
$record = self::reloadRecord($rid);
|
||||
if (!$record) {
|
||||
return ['ok' => false, 'msg' => __('No active game in progress')];
|
||||
}
|
||||
@@ -346,10 +363,10 @@ final class GameLiveService
|
||||
return ['ok' => false, 'msg' => __('Game live: settlement error') . ': ' . $e->getMessage()];
|
||||
}
|
||||
|
||||
GameHotDataRedis::gameRecordForget((int) $record['id']);
|
||||
GameHotDataCoordinator::afterGameRecordCommitted($rid);
|
||||
|
||||
try {
|
||||
GameRecordStatService::refreshForRecordId((int) $record['id']);
|
||||
GameRecordStatService::refreshForRecordId($rid);
|
||||
} catch (Throwable) {
|
||||
}
|
||||
JackpotPushService::publishHits($settleOut['jackpot_hits'] ?? []);
|
||||
@@ -365,6 +382,9 @@ final class GameLiveService
|
||||
'estimated_loss' => $finalLoss,
|
||||
'payout_until' => $payoutUntil,
|
||||
];
|
||||
} finally {
|
||||
GameHotDataLock::release(GameHotDataLock::TYPE_GAME_RECORD, (string) $rid, $lock['token'], $lock['redis_lock']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,22 +402,30 @@ final class GameLiveService
|
||||
return;
|
||||
}
|
||||
$id = (int) $row['id'];
|
||||
Db::startTrans();
|
||||
try {
|
||||
Db::name('game_record')->where('id', $id)->update([
|
||||
'status' => 4,
|
||||
'payout_until' => null,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
GameRecordService::createNextRecordAfterDraw();
|
||||
Db::commit();
|
||||
} catch (Throwable) {
|
||||
Db::rollback();
|
||||
$lock = GameHotDataLock::tryAcquireWithWait(GameHotDataLock::TYPE_GAME_RECORD, (string) $id, 2000);
|
||||
if (!$lock['acquired']) {
|
||||
return;
|
||||
}
|
||||
GameHotDataRedis::gameRecordForget($id);
|
||||
GameRecordStatService::refreshForRecordId($id);
|
||||
self::publishSnapshot(null);
|
||||
try {
|
||||
Db::startTrans();
|
||||
try {
|
||||
Db::name('game_record')->where('id', $id)->update([
|
||||
'status' => 4,
|
||||
'payout_until' => null,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
GameRecordService::createNextRecordAfterDraw();
|
||||
Db::commit();
|
||||
} catch (Throwable) {
|
||||
Db::rollback();
|
||||
return;
|
||||
}
|
||||
GameHotDataCoordinator::afterGameRecordCommitted($id);
|
||||
GameRecordStatService::refreshForRecordId($id);
|
||||
self::publishSnapshot(null);
|
||||
} finally {
|
||||
GameHotDataLock::release(GameHotDataLock::TYPE_GAME_RECORD, (string) $id, $lock['token'], $lock['redis_lock']);
|
||||
}
|
||||
}
|
||||
|
||||
public static function tickAutoDraw(): void
|
||||
@@ -609,7 +637,7 @@ final class GameLiveService
|
||||
'status' => 1,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
GameHotDataRedis::gameRecordForget($recordId);
|
||||
GameHotDataCoordinator::afterGameRecordCommitted($recordId);
|
||||
$record['status'] = 1;
|
||||
self::publishPublicPeriodLocked($record);
|
||||
}
|
||||
@@ -629,7 +657,7 @@ final class GameLiveService
|
||||
$update['status'] = 1;
|
||||
}
|
||||
Db::name('game_record')->where('id', $recordId)->update($update);
|
||||
GameHotDataRedis::gameRecordForget($recordId);
|
||||
GameHotDataCoordinator::afterGameRecordCommitted($recordId);
|
||||
$record = array_merge($record, $update);
|
||||
if ($st === 0) {
|
||||
self::publishPublicPeriodLocked($record);
|
||||
|
||||
Reference in New Issue
Block a user