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

生產環境 MySQL 事務長時間 RUNNING 排查:未捕獲異常導致事務未提交

     編輯:MySQL 綜合教學

生產環境 MySQL 事務長時間 RUNNING 排查:未捕獲異常導致事務未提交

運營反饋訂單提交卡住,應用與 DB 負載正常,無鎖等待。通過 INNODB_TRX 發現兩個事務長期 RUNNING,定位到具體 SQL 與應用 IP,最終在 Java 代碼中發現 catch (SQLException e) { } 吞噬異常且未 rollback(),導致事務懸掛。

排查鏈路

  1. SELECT * FROM information_schema.INNODB_TRX\G → 獲取 trx_mysql_thread_id。
  2. SELECT * FROM information_schema.PROCESSLIST WHERE ID=trx_mysql_thread_id → 獲取客戶端 IP:Port。
  3. 登入應用伺服器,對應 Tomcat 線程日志,找到具備報錯堆棧的業務代碼。
  4. 代碼審查發現:
try {
    // 多條 DML
} catch (SQLException e) {
    // 空 catch,未 rollback,未拋出
}

根因

異常發生後未 rollback(),連接歸還池時仍處於事務中,後續複用該連接的請求會被阻塞或髒讀,最終導致業務卡死。

修復與規範

規範代碼模板
必須 rollback
Connection conn = null;
try {
    conn = ds.getConnection();
    conn.setAutoCommit(false);
    // ... DML
    conn.commit();
} catch (SQLException e) {
    if (conn != null) conn.rollback();
    throw new BizException(e);
} finally {
    if (conn != null) conn.close();
}
使用 Spring @Transactional 聲明式事務自動回滾 RuntimeException/Error,rollbackFor=Exception.class 覆蓋檢查型異常。
連接池驗證 HikariCP connectionTestQuery=SELECT 1、maxLifetime 避免殭屍連接。

監控預警

  • 定時查詢 INNODB_TRX 過濾 trx_started < NOW() - INTERVAL 60 SECOND 告警。
  • 應用層埋點:事務開啟/提交/回滾耗時上報,超過閾值報警。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved