首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

WebLogic XAER_NOTA 異常兩大根因深度解析:事務分支超時與多數據源指向同連接池配置錯誤

     編輯:Java 相關知識

WebLogic 執行 XA 事務時遇到 XAER_NOTA: The XID is not valid,意味著資源管理器 (RM: DB/MQ) 端找不到對應的事務分支。本文深度剖析兩大根因:**分支被 RM 超時清理**與**多 XA DataSource 指向同一連接池導致 XAResource 身份混淆**,並給出配置級與代碼級解決方案。

XAER_NOTA 含義

XAER_NOTA = 事務分支在 RM 端不存在。兩種可能:1) 分支被超時清理;2) 分支壓根未在 RM 端發起。

根因一:事務分支被 RM 超時清理 (配置級解決)

機制

  • WebLogic 調用 xaStart() 時可通知 RM 分支超時時間。
  • 若未配置,RM 使用默認超時 (Oracle 默認 60 秒檢測,~120 秒實際清理)。
  • 長事務執行超過 RM 超時 → 分支被 RM 回滾/清理 → 後續 xaStart/xaEnd 拋 XAER_NOTA。

解決方案:啟用 WebLogic XA Transaction Timeout

  1. 數據源配置 → 事務標籤 → 勾選 Enable XA Transaction Timeout。
  2. 設置 XA Transaction Timeout 值 > Global Transaction Timeout (建議大 10~20%)。
  3. 效果:WebLogic 在 xaStart() 時傳遞超時時間給 RM,RM 據此延長分支保留期限。

根因二:多 XA DataSource 指向同一連接池 — XAResource 身份衝突 (架構級錯誤)

錯誤配置拓撲

XADatasource_11 → XAPool_A → Database_A
XADatasource_21 → XAPool_B → Database_B

// 業務需求新增別名數據源,錯誤指向同池
XADatasource_12 → XAPool_A  (同池!)
XADatasource_22 → XAPool_B  (同池!)

WebLogic 部署邏輯導致的災難

  1. 部署 XA DataSource 時,調用 registerResource(poolName, XAResource, props) 註冊到 **Process-wide resourceDescriptorList**。
  2. 註冊前先 unregisterResource(poolName) 移除舊同名資源。
  3. 結果:部署 XADatasource_12 導致 XADatasource_11 在 resourceDescriptorList 中被移除!同理 22 移除 21。

運行時事務 Enlist 過程 (以 XADatasource_11 為例)

// 1. 獲取連接 → enlistResource(XAResource)
ServerTransactionImpl.enlistResource(xar)

// 2. 檢查 resourceDescriptorList 中是否有 XADatasource_11 對應的描述符
//    → 不在 (已被 12 移除)

// 3. 檢查 transaction-wide resourceInfoList
//    → 空 (新事務)

// 4. 創建 XAServerResourceInfo(xar)
//    → 再次查 resourceDescriptorList,按實例不存在,按類名 "weblogic.jdbc.jta.DataSource" 找到 XADatasource_12 的描述符
//    → 復用該描述符,resourceInfo.name = "weblogic.jdbc.jta.DataSource"

// 5. resourceInfoList 中無同名 → enlistElseWhere = false → 傳 TMNOFLAGS (新分支)
//    → xaStart(xid, TMNOFLAGS) → Database_A 創建新分支 ✓

// 6. 後續獲取 XADatasource_21 連接
//    → 同邏輯,resourceInfo.name 同為 "weblogic.jdbc.jta.DataSource"
//    → 發現 resourceInfoList 中已有同名 → enlistElseWhere = true
//    → 傳 TMJOIN (加入現有分支) → xaStart(xid, TMJOIN) 發送給 Database_B
//    → Database_B 無此全局事務對應分支 → **XAER_NOTA 爆發!**

核心矛盾

  • 邏輯上:兩個不同數據源 (11/21) 對應兩個不同數據庫 (A/B),應創建**兩個獨立分支** (TMNOFLAGS 兩次)。
  • 實際上:因共用類名 weblogic.jdbc.jta.DataSource 作為 resourceInfo.name,第二個被誤判為「已在別處 enlist」,強行 TMJOIN 導致跨庫分支錯位。

官方定性:WAD (Work As Designed)

WebLogic 限制:**同一進程中,多個 XA DataSource 不得指向同一連接池**,也不得多個連接池指向同一數據庫 (若共用 XAResource 實現類)。違反此限制屬於配置錯誤,非產品 Bug。WebLogic 8.1 SP6 已輸出明確錯誤提示。

解決方案與最佳實踐

場景正確做法
需要多個邏輯數據源訪問同一物理庫使用 **Multi Data Source** (負載均衡/故障轉移) 或單一 DataSource 供多模塊共用,**嚴禁創建多個 XA DataSource 指向同一 Pool**
需要隔離事務邊界不同事務域使用**不同連接池 + 不同物理數據庫實例/Schema**
長事務超時風險啟用 Enable XA Transaction Timeout,設置合理值 (> 全局事務超時)
監控與告警監控 XAER_NOTA 異常計數、事務超時率、連接池 NumUnavailable

總結

XAER_NOTA 要么是**時間維度**上的超時清理 (配置 XA Transaction Timeout 解決),要么是**身份維度**上的資源混淆 (避免多 XA DataSource 共用 Pool/DB)。前者是參數調優,後者是架構原則 —— **一個 XA 連接池只對應一個邏輯 XA DataSource,一個物理數據庫實例建議只對應一個 XA 連接池**。

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