From ebb17d69bfda40813bf317c076df9cb849f61963 Mon Sep 17 00:00:00 2001 From: youpaishidifu <1@ypshidifu.cn> Date: Mon, 5 Oct 2026 17:00:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=A4=E6=98=93=E6=8E=A8=E6=B5=81=E5=8A=A015?= =?UTF-8?q?=E7=A7=92=E5=9B=9E=E6=89=A7=E7=AA=97=E5=8F=A3=EF=BC=9A=E6=94=B6?= =?UTF-8?q?=E5=88=B0PHP=E5=9B=9E=E6=89=A7=E6=89=8D=E6=8E=A8=E4=B8=8B?= =?UTF-8?q?=E4=B8=80=E6=89=B9=EF=BC=8C=E6=9C=AA=E6=94=B6=E5=88=B0=E5=88=99?= =?UTF-8?q?=E7=AD=8915=E7=A7=92=E9=87=8D=E8=AF=95=E5=90=8C=E4=B8=80?= =?UTF-8?q?=E6=89=B9=EF=BC=88=E5=B8=A620=E6=AC=A1=E4=B8=8A=E9=99=90?= =?UTF-8?q?=EF=BC=89=EF=BC=8C=E6=89=B9=E8=B0=83=E5=BA=A6=E7=BA=B3=E5=85=A5?= =?UTF-8?q?=E9=94=81=E5=BA=93=E9=80=80=E9=81=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Sdf1_login/WebManager.java | 51 +++++++++++++++++++----- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main/java/Sdf1_login/WebManager.java b/src/main/java/Sdf1_login/WebManager.java index cba3c59..d17f574 100644 --- a/src/main/java/Sdf1_login/WebManager.java +++ b/src/main/java/Sdf1_login/WebManager.java @@ -5367,7 +5367,17 @@ public class WebManager { /** 节流:纯对账(不推送)的批次走短间隔;真正推了 PHP 的批次走长间隔,别把 PHP 压太狠 */ private static final long TX_SYNC_VERIFY_STEP_MS = 400; - private static final long TX_SYNC_PUSH_STEP_MS = 1500; + + // ★ 回执窗口(2026-10-05 阶段D):大笔数推流时 PHP 可能还在处理上一批, + // 连续硬推会吃 500(database is locked)。改为—— + // 推一批 → 等 PHP 回执(HTTP success 即回执)→ 收到才推下一批并再等 15 秒; + // 没收到回执则等 15 秒后重试【同一批】(不推进水位线,不丢数据)。 + /** 真推了 PHP 且收到回执:下一批前的冷却窗口 */ + private static final long TX_SYNC_RECEIPT_STEP_MS = 15000; + /** 没收到回执:等这么久后重试同一批 */ + private static final long TX_SYNC_RECEIPT_RETRY_MS = 15000; + /** 同一批连续重试上限(15s × 20 ≈ 5 分钟),超限才中止本轮,下轮从原位置继续 */ + private static final int TX_SYNC_MAX_BATCH_RETRIES = 20; public void syncBondTransactions() { if (!enabled) return; @@ -5422,9 +5432,10 @@ public class WebManager { new BukkitRunnable() { int index = 0; - int batchNo = 0; int okCount = 0; int pushedCount = 0; + /** 当前批的连续失败次数(收到回执推进后清零) */ + int batchRetries = 0; @Override public void run() { @@ -5441,7 +5452,8 @@ public class WebManager { return; } - batchNo++; + // ★ 批号由 index 推导:重试同一批时批号保持不变,日志不虚增 + final int batchNo = index / TX_SYNC_BATCH_SIZE + 1; List> batch = queue.subList(index, Math.min(index + TX_SYNC_BATCH_SIZE, queue.size())); @@ -5458,33 +5470,50 @@ public class WebManager { } if (!ok) { - // ★ 本批失败:立即中止,不推进水位线 → 下轮从同一位置重试 - plugin.getLogger().warning("[Web交易同步] 第" + batchNo + "批失败,已中止推送," - + "剩余 " + (total - okCount) + " 笔将在下轮重试(不丢数据)"); - finishTxBatchRun(); + // ★ 没收到 PHP 回执(500 / 超时 / 锁库):不中止、不推进水位线, + // 等 15 秒后重试【同一批】;连续超限才收尾,剩余笔数下轮继续(不丢数据) + batchRetries++; + if (batchRetries > TX_SYNC_MAX_BATCH_RETRIES) { + plugin.getLogger().warning("[Web交易同步] 第" + batchNo + + "批连续 " + TX_SYNC_MAX_BATCH_RETRIES + " 次未收到回执,本轮中止,剩余 " + + (total - okCount) + " 笔将在下轮重试(不丢数据)"); + finishTxBatchRun(); + return; + } + plugin.getLogger().warning("[Web交易同步] 第" + batchNo + "批未收到 PHP 回执," + + (TX_SYNC_RECEIPT_RETRY_MS / 1000) + " 秒后重试同一批(第 " + + batchRetries + "/" + TX_SYNC_MAX_BATCH_RETRIES + " 次)"); + scheduleTxStep(this, TX_SYNC_RECEIPT_RETRY_MS); return; } + batchRetries = 0; okCount += batch.size(); pushedCount += pushed; index += TX_SYNC_BATCH_SIZE; - // ★ 悠着点推:真推了 PHP 的批次多等一会儿,纯对账跳过的批次快些过去 - scheduleTxStep(this, pushed > 0 ? TX_SYNC_PUSH_STEP_MS : TX_SYNC_VERIFY_STEP_MS); + // ★ 回执节奏:HTTP success 即回执,收到才推下一批; + // 真推了 PHP 的批次再冷却 15 秒让 PHP 消化,纯对账跳过的批次走短间隔 + scheduleTxStep(this, pushed > 0 ? TX_SYNC_RECEIPT_STEP_MS : TX_SYNC_VERIFY_STEP_MS); } }.runTaskLaterAsynchronously(plugin, 1L); } - /** 调度下一批(延时让出线程,插件关闭时静默收尾) */ + /** 调度下一批(延时让出线程,插件关闭时静默收尾;PHP 锁库退避窗口内不硬闯) */ private void scheduleTxStep(Runnable step, long delayMs) { + long wait = Math.max(1L, delayMs); + long busyLeft = phpBusyUntil - System.currentTimeMillis(); + if (busyLeft > 0) { + wait = Math.max(wait, busyLeft + 2000); + } try { new BukkitRunnable() { @Override public void run() { step.run(); } - }.runTaskLaterAsynchronously(plugin, Math.max(1L, delayMs)); + }.runTaskLaterAsynchronously(plugin, wait); } catch (Exception e) { plugin.getLogger().warning("[Web交易同步] 批次调度失败,本轮中止: " + e.getMessage()); finishTxBatchRun();