為什麼事務以分佈式方式執行 (DTCXact)?
我實際上是在嘗試分析和解決一些經常發生的死鎖,這些死鎖都包括至少一個名為“DTCXact”的事務,這讓我問。
我對生產伺服器重複執行以下查詢:
SELECT DTAT.transaction_id , DTAT.[name] , DTAT.transaction_begin_time , CASE DTAT.transaction_type WHEN 1 THEN 'Read/write' WHEN 2 THEN 'Read-only' WHEN 3 THEN 'System' WHEN 4 THEN 'Distributed' END AS transaction_type , CASE DTAT.transaction_state WHEN 0 THEN 'Not fully initialized' WHEN 1 THEN 'Initialized, not started' WHEN 2 THEN 'Active' WHEN 3 THEN 'Ended' -- only applies to read-only transactions WHEN 4 THEN 'Commit initiated'-- distributed transactions only WHEN 5 THEN 'Prepared, awaiting resolution' WHEN 6 THEN 'Committed' WHEN 7 THEN 'Rolling back' WHEN 8 THEN 'Rolled back' END AS transaction_state , CASE DTAT.dtc_state WHEN 1 THEN 'Active' WHEN 2 THEN 'Prepared' WHEN 3 THEN 'Committed' WHEN 4 THEN 'Aborted' WHEN 5 THEN 'Recovered' END AS dtc_state FROM sys.dm_tran_active_transactions DTAT INNER JOIN sys.dm_tran_session_transactions DTST ON DTAT.transaction_id = DTST.transaction_id WHERE [DTST].[is_user_transaction] = 1 ORDER BY DTAT.transaction_begin_time
它總是顯示類似於此範例的結果:
2414848764;DTCXact;2016-01-28 10:24:41.983;分佈式;已送出;已送出 2414896908;DTCXact;2016-01-28 10:26:05.847;分佈式;已送出;已送出 2414903917;DTCXact;2016-01-28 10 :26:29.017;分佈式;已送出;已送出 2414918503;user_transaction;2016-01-28 10:27:06.823;讀/寫;活動;NULL 2414918551;DTCXact;2016-01-28 10:27:06.973;分佈式;已送出;堅定的
此結果表明大多數事務以分佈式方式執行。我真的完全不知道為什麼。一些伺服器集群有兩個節點。其他人不是。他們的結果是相似的。
事實:
- MSDTC 服務正在所有 SQL 伺服器上執行。沒有一個 SQL-Server 有任何連結伺服器。
remote trans proc
在 sys.configurations 中設置為 0。- 我發現程式碼中沒有明確
Begin DISTRIBUTED Transaction
或SET REMOTE_PROC_TRANSACTIONS
用法TransactionScope
程式碼中沒有定義/用法- 找到一個類描述如下:
//COM+ Transaction mgr using "Service without Components" model built according to System.Transactions.TransactionScope (NET 2). I don't know what this means.
導致這些事務的 asp.net Web 應用程序通常總是從同一個 SQL-Server 上的同一個數據庫讀取和寫入數據。可能有一些非常少的例外,尤其是在夜間複製一些數據時執行,但我不希望看到大部分事務被分發一整天。
我跟踪了一個 SPID 的行為,發現它正在執行分佈式事務:
這是跟踪的範例結果:我看到連續幾十個
RPC:Completed
事件,然後是 2 個DTCTransaction
事件(第一個:EventSubClass="Enlisting in a DTC transaction
",第二個 EventSubclass="Propagate Transaction
")。都針對同一個數據庫。沒有TM:Promote Tran xxx
事件發生。我發現這些查詢正在 .net Windows 服務中的 IIS(託管 Web 應用程序的地方)上執行,該服務也使用相同的數據庫並執行作業。這第二次申請會導致 DTC 嗎?
我在網上搜尋,沒有找到類似的問題或任何答案。所以我想知道這可能是什麼原因?或者我錯過了什麼知識來理解這一點?
您是否嘗試過分析單個會話以查看其事務是否/何時提升為分佈式?例如,使用伺服器端跟踪,例如
DTCTransaction
(並且可能TM: Promote Tran xxx
)事件類。您還可以在 Windows 中監視詳細的DTC 活動。我會為單個 SPID 分析所有可能看起來的連接、執行和與事務相關的事件,同時它會執行一些具有代表性的工作。注意:由於成本的原因,最好在測試系統上進行分析,使用伺服器端跟踪或擴展事件等效項。如果您確實沒有其他選擇,請不要在本地測試實例上使用 Profiler UI。
如果我無法看到應用程序原始碼或無法與開發人員討論事務的使用,這很可能是我開始隔離原因的方式。
也可能是應用程序、其數據訪問層或客戶端驅動程序設置為在訪問第二個本地數據庫或在同一事務中使用第二個連接時促進事務。甚至可能有一個明確的
BEGIN DISTRIBUTED TRANSACTION
. 也許TransactionScope
(或類似的)在 ADO.NET 中使用了多個連接。看:有很多可能性,但是跟踪/分析至少會給你一些關於你的調查重點的線索。
我的猜測是,這很可能是您的應用程序開發人員使用 .NET 連接和事務的方式的意外副作用,可能與 IIS 的配置方式相結合。
分佈式事務似乎確實可能以某種方式與您的“事務管理器”類相關聯。您的程式碼中不必有明確的TransactionScope,這只是一個常見的向量。
在觀察對 DTC 和 SQL Server 的影響的同時逐步檢查應用程式碼(和數據訪問組件)可能是準確確定呼叫或徵用分佈式事務的位置、時間和原因的最佳方法。
現在已過時問題已被編輯,但其他原因包括:
remote proc transaction promotion
設置為 true 的連結伺服器。這可能導致本地事務被提升為分佈式事務。- sys.configurations中的舊配置設置
remote trans proc
,與“遠端伺服器”一起使用時。另請參閱會話選項。SET REMOTE_PROC_TRANSACTIONS
該應用程序是在 MARS 支持可用之前編寫的嗎?
檢查您的應用在單個事務中打開了多少個連接。如果您打開多個連接並將它們登記在同一個事務中,那麼即使這些連接指向同一個數據庫,該事務也會提升到 DTC。