代码提交
This commit is contained in:
@@ -1661,17 +1661,49 @@ class Adapter implements WeChatServiceInterface
|
||||
|
||||
|
||||
$offset = 0;
|
||||
$limit = 2000;
|
||||
// 降低单批规模,减少长事务导致的锁冲突窗口
|
||||
$limit = 500;
|
||||
$usleepTime = 50000;
|
||||
$maxRetry = 5;
|
||||
// 在会话级别降级隔离级别,避免 SELECT 阶段持有共享锁导致与业务更新互斥
|
||||
Db::execute("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED");
|
||||
do {
|
||||
$affected = Db::execute($sql, [$offset, $limit]);
|
||||
$offset += $limit;
|
||||
$retry = 0;
|
||||
while (true) {
|
||||
try {
|
||||
$affected = Db::execute($sql, [$offset, $limit]);
|
||||
break;
|
||||
} catch (\Throwable $e) {
|
||||
$retry++;
|
||||
if (!$this->isDeadlockOrLockWaitTimeout($e) || $retry >= $maxRetry) {
|
||||
throw $e;
|
||||
}
|
||||
// 指数退避,给冲突事务让路
|
||||
usleep(100000 * $retry);
|
||||
Log::warning("syncTrafficSourceGroup 批处理发生锁冲突,正在重试: offset={$offset}, retry={$retry}, error=" . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if ($affected > 0) {
|
||||
$offset += $limit;
|
||||
usleep($usleepTime);
|
||||
}
|
||||
} while ($affected > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为死锁或锁等待超时
|
||||
*/
|
||||
protected function isDeadlockOrLockWaitTimeout(\Throwable $e): bool
|
||||
{
|
||||
$msg = strtolower($e->getMessage());
|
||||
return strpos($msg, 'deadlock found') !== false
|
||||
|| strpos($msg, 'lock wait timeout exceeded') !== false
|
||||
|| strpos($msg, '1213') !== false
|
||||
|| strpos($msg, '1205') !== false
|
||||
|| strpos($msg, '40001') !== false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// V2 流量池数据同步方法
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user