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

MySQL 事務長時間 RUNNING 導致 Transaction Timed Out 死線問題排查實戰

     編輯:MySQL 綜合教學

從「Transaction timed out: deadline」到長事務未提交的根因定位全過程

應用拋出 TransactionTimedOutException,疑似表鎖,實則為**事務長時間處於 RUNNING 狀態未提交/回滾**,導致後續查詢被阻塞超時。本文記錄完整排查鏈路:現象 → 系統表分析 → Binlog 定位業務代碼 → 代碼修復驗證。

一、故障現象

org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was Tue Nov 25 13:33:07 CST 2014
Caused by: ... Deadline was ... (Spring 事務管理器檢測到事務超過配置超時時間)

SQL 為簡單聯表查詢,無複雜邏輯。

二、InnoDB 系統表排查 — 無鎖等待,只有長事務

SHOW ENGINE INNODB STATUS;  -- 無死鎖信息
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;  -- 關鍵發現

結果顯示多個事務 trx_state = RUNNING,trx_started 早於故障時間,trx_query = NULL (無活動語句),INNODB_LOCKS、INNODB_LOCK_WAITS 皆為空。**結論:非鎖阻塞,純屬事務懸掛未結束。**

三、臨時止血

KILL ;  -- 終結懸掛事務所在線程

四、問題復現與 Binlog 定位業務

  1. 再次觀察 INNODB_TRX 捕獲新懸掛事務 (thread_id=942663)。
  2. Slow Log 無記錄 → Binlog 分析該線程:
    # Binlog 事件
    BEGIN;
    INSERT INTO `SHOP_CASH_COUPON_USER_REF` ...;
    UPDATE `CASH_TICKET` ...;
    COMMIT;  -- 時間點 17:41:10
  3. 時間高度吻合,定位到業務模塊「優惠券發放/核銷」相關代碼。

五、代碼根因與修復

該業務方法異常處理塊缺少 COMMIT 或 ROLLBACK,導致拋出異常後事務懸掛。Spring 聲明式事務默認僅對未檢查異常回滾,若捕獲異常未重拋或手動提交,事務不會自動結束。

// 修復前
try {
    // DML 操作
} catch (Exception e) {
    log.error(e);  // 吞掉異常,事務懸掛
}

// 修復後
try {
    // DML 操作
} catch (Exception e) {
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // 手動標記回滾
    throw e; // 或重拋讓 Spring 捕獲回滾
}

六、驗證結果

修復部署後壓測 N 次,INNODB_TRX 無殘留 RUNNING 事務,應用無超時報錯。

七、額外發現:Binlog Format 與隔離級衝突

Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT
and at least one table uses a storage engine limited to row-based logging.
InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.

解決: SET GLOBAL BINLOG_FORMAT = MIXED; (或 ROW),兼容 READ COMMITTED 隔離級。

八、深度思考:為何懸掛事務阻塞後續 SELECT?

推測:懸掛事務持有排他鎖 (X Lock) (源於前序 INSERT/UPDATE),後續 SELECT 需共享鎖 (S Lock),X 與 S 互斥導致阻塞。源碼層面涉及 lock_rec_convert_impl_to_expl、lock_wait_suspend_thread 等鎖等待邏輯,待後續深入。

九、總結與建議

  • 監控 INNODB_TRX 長事務告警 (超 60s 即報警)。
  • 代碼規範:異常處理**必須**顯式 ROLLBACK 或重拋異常交由框架管理。
  • Binlog Format 設置 MIXED 平衡兼容性與復制一致性。
  • Spring @Transactional 配置 rollbackFor = Exception.class 覆蓋受檢異常。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved