動作
Bug #1523
進行中Bug #1518: [Backend Bug] StopTransaction 補送失敗後保留殭屍交易,Connector 無法再次充電
[Backend Bug][#1518-R5] CP 單一 MeterValues batch 失敗會阻斷後續 Connector
狀態:
New
優先權:
Normal
被分派者:
-
開始日期:
2026-09-28
完成日期:
預估工時:
概述
背景¶
本票是 #1518 的子票,來源為 2026-09-28 對 MeterValues 第二~第五階段實作的 Astra 程式審查。該實作目前只存在主要 workspace,尚未部署至 A17;A17 已套用的第一階段複合索引不受本票影響。
工作位置:
- EMS workspace:
/Users/ken/Documents/workspace/workspace_cloudlink/ems - EMS branch:
feature/redmine-1517-ocpp-liveness -
java/charge_point為獨立 repository,使用相同 branch 名稱 - 直接使用主要 workspace,不建立 worktree
- 未經 Ken 指示不得部署或重啟案場服務
問題¶
CP queue 改成 batch 後,loadInRequestedOrder() 位於每組例外隔離之外。第一組 entity 載入/轉換失敗時,例外直接離開整輪 processMeterValuesQueue(),後續正常 transaction batch、其他 Connector 與無交易 MeterValues 都不再處理。
失敗組也沒有進入 batch retry 更新。若相同壞資料每輪都失敗,排程可能長期卡在同一位置。
審查重現:第一組模擬載入失敗,第二個 Connector 正常;正常組預期送出一次,實際零次,DataRetrievalFailureException 直接逸出。
影響¶
- 一筆壞資料可能阻斷整台 CP 的 MeterValues 上報。
- 後續健康 Connector 的即時資料及交易 MeterValues 延遲。
- 失敗資料可能沒有 retry/failure 狀態,形成永久卡點。
相關程式¶
java/charge_point/.../TransactionMessageQueue.javajava/charge_point/.../MeterValueRepository.javajava/charge_point/.../OcppTransactionMessageService.java
建議修正¶
- 每一個 batch 的 reload、驗證、send、success/retry 更新都有自己的例外邊界。
- 單組失敗後記錄 chargePoint、connector、transaction、timestamp 及 IDs,繼續下一組。
- 將 sent/retry 更新移至獨立 Spring service,以 public
@Transactional(REQUIRES_NEW)method 執行;避免 private self-invocation 使 transaction annotation 不生效。 - 非同步 callback 的狀態更新失敗也必須記錄及監控,不能成為無人觀察的 future exception。
- 評估 SENDING/in-flight claim 與 timeout,避免上一個 OCPP request 未完成時,下一輪 scheduler 重送同一 batch。
- 整組收到 CALLRESULT 後才一起標記 sent;失敗不得標記假成功。
驗收條件¶
- 第一組載入失敗時,第二個正常 Connector 仍成功送出。
- 有交易 batch 失敗時,無交易 MeterValues 仍繼續處理,反向亦同。
- 覆蓋同步拋例外、future exceptional completion、sent 更新失敗及 retry 更新失敗。
- 單組失敗具有可追蹤 retry/failure 記錄,不會永久阻斷排程。
- 上一個 request 尚未完成時,下一輪 scheduler 不得重複送出同一 batch。
- 成功與失敗均維持整組一致性,不出現部分 sent、部分 retry。
重現¶
python3 test_report/evidence/1518-review/run_one.py cp-batch-failure
審查時健康 Connector 預期送出 1 次、實際 0 次,例外直接逸出。
沒有任何資料可供顯示
動作