首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 事務 Rollback 失效真兇:網絡抖動導致 BEGIN 丟失,連接重置變 Autocommit

     編輯:MySQL 綜合教學

MySQL 事務 Rollback 失效真兇:網絡抖動導致 BEGIN 丟失,連接重置變 Autocommit

支付業務出現詭異現象:事務失敗調用 ROLLBACK,只有最後一條 SQL 回滾,前面的寫操作全部生效。排查發現:網絡抖動導致首次建立連接時發送的 BEGIN 丟包,驅動自動重連後會話變為 autocommit=ON,後續所有語句隱式提交,ROLLBACK 自然無法回滾已提交的語句。

根因還原

  1. 應用發送 BEGIN → 網絡丟包,MySQL 未收到。
  2. 連接斷開,連接池/驅動自動重連(autoReconnect=true)。
  3. 新連接預設 autocommit=1,應用不知情繼續執行 DML。
  4. 每條 DML 隱式提交,事務實際上已不存在。
  5. 異常捕獲調用 ROLLBACK,僅回滾最後一條隱式事務。

臨時方案:應用層時間戳驗證

在 BEGIN 時將應用伺服器時間戳寫入一張專用表(或用戶變數),後續每條 SQL 執行前讀取比對;時間戳不一致則判定連接已重置,拋棄重試。缺點:每條 SQL 額外一次網絡往返,效能大幅下降。

更優雅的最佳實踐

方案原理適用場景
關閉自動重連 JDBC autoReconnect=false、HikariCP autoCommit=false,拋出異常由上層統一重試 所有生產環境,強制業務感知連接失敗
使用 XA 事務 / 分佈式事務管理器 全局事務 ID 確保原子性,跨節點亦可回滾 微服務、跨庫事務
應用層冪等 + 重試 業務邏輯冪等設計,連接斷開直接重試整個事務邏輯 高可用架構,配合重試框架(如 Resilience4j)
驅動層連接驗證 connection.isValid(1) 或 SELECT 1 校驗連接存活,失效則重建並重新 BEGIN 舊系統無法改造自動重連行為時

核心原則

永遠不要依賴驅動自動重連維持事務上下文。 事務邊界必須由應用顯式控制,連接異常即拋棄整個事務上下文重試。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved