如何确定分布式事务超时的原因

8
我正在使用LINQ to SQL和支持分布式事务的第三方SDK。当我意识到一个待处理的更新将会更新SQL记录和第三方SDK中的记录时,我创建了一个TransactionScope,并设置了0(无限)超时时间(尽管我也尝试过12小时作为TimeSpan参数)。然后,我在环境事务上使用GetDtcTransaction来获取一个DTC事务,以链接到第三方SDK。一切都很好地工作了大约10分钟,但是10分钟后,事务消失了并出现了错误。如何确定事务为什么消失?我怀疑这是一个超时问题,因为即使在此时点完成了稍微不同程度的工作,它也经常在10分钟后发生。但我不知道如何确定是什么终止了事务,为什么以及如何延长其生命周期。
我已经尝试使用SQL Profiler跟踪以下事件:
1. 所有错误和警告事件 2. 除“审核模式对象”事件之外的所有安全事件 3. 除SQLTransaction和TransactionLog事件之外的所有事务事件
但在错误发生时,我只得到了以下事件:
<Event id="19" name="DTCTransaction">
  <Column id="3" name="DatabaseID">1</Column>
  <Column id="11" name="LoginName">sa</Column>
  <Column id="35" name="DatabaseName">master</Column>
  <Column id="51" name="EventSequence">167065</Column>
  <Column id="12" name="SPID">10</Column>
  <Column id="60" name="IsSystem">1</Column>
  <Column id="1" name="TextData">{D662BBC4-21EC-436D-991C-DCB061A34782}</Column>
  <Column id="21" name="EventSubClass">16</Column>
  <Column id="25" name="IntegerData">0</Column>
  <Column id="41" name="LoginSid">01</Column>
  <Column id="49" name="RequestID">0</Column>
  <Column id="2" name="BinaryData">C4BB62D6EC216D43991CDCB061A34782</Column>
  <Column id="14" name="StartTime">2009-11-11T13:55:32.82-06:00</Column>
  <Column id="26" name="ServerName">.</Column>
  <Column id="50" name="XactSequence">0</Column>
</Event>
<Event id="33" name="Exception">
  <Column id="3" name="DatabaseID">9</Column>
  <Column id="11" name="LoginName">sa</Column>
  <Column id="31" name="Error">1222</Column>
  <Column id="35" name="DatabaseName">ACS</Column>
  <Column id="51" name="EventSequence">167066</Column>
  <Column id="12" name="SPID">19</Column>
  <Column id="20" name="Severity">16</Column>
  <Column id="60" name="IsSystem">1</Column>
  <Column id="1" name="TextData">Error: 1222, Severity: 16, State: 18</Column>
  <Column id="41" name="LoginSid">01</Column>
  <Column id="49" name="RequestID">0</Column>
  <Column id="14" name="StartTime">2009-11-11T13:55:34.717-06:00</Column>
  <Column id="26" name="ServerName">.</Column>
  <Column id="30" name="State">18</Column>
  <Column id="50" name="XactSequence">0</Column>
</Event>
<Event id="33" name="Exception">
  <Column id="31" name="Error">8525</Column>
  <Column id="8" name="HostName">MARTY755</Column>
  <Column id="12" name="SPID">55</Column>
  <Column id="20" name="Severity">16</Column>
  <Column id="64" name="SessionLoginName">fse</Column>
  <Column id="1" name="TextData">Error: 8525, Severity: 16, State: 1</Column>
  <Column id="9" name="ClientProcessID">2516</Column>
  <Column id="41" name="LoginSid">DB2744F54B5CDB4A8B9E5CA9C209A7AC</Column>
  <Column id="49" name="RequestID">0</Column>
  <Column id="10" name="ApplicationName">.Net SqlClient Data Provider</Column>
  <Column id="14" name="StartTime">2009-11-11T13:55:37.54-06:00</Column>
  <Column id="26" name="ServerName">.</Column>
  <Column id="30" name="State">1</Column>
  <Column id="50" name="XactSequence">236223201284</Column>
  <Column id="3" name="DatabaseID">9</Column>
  <Column id="11" name="LoginName">fse</Column>
  <Column id="35" name="DatabaseName">ACS</Column>
  <Column id="51" name="EventSequence">167067</Column>
</Event>
<Event id="162" name="User Error Message">
  <Column id="31" name="Error">8525</Column>
  <Column id="8" name="HostName">MARTY755</Column>
  <Column id="12" name="SPID">55</Column>
  <Column id="20" name="Severity">16</Column>
  <Column id="64" name="SessionLoginName">fse</Column>
  <Column id="1" name="TextData">Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.</Column>
  <Column id="9" name="ClientProcessID">2516</Column>
  <Column id="41" name="LoginSid">DB2744F54B5CDB4A8B9E5CA9C209A7AC</Column>
  <Column id="49" name="RequestID">0</Column>
  <Column id="10" name="ApplicationName">.Net SqlClient Data Provider</Column>
  <Column id="14" name="StartTime">2009-11-11T13:55:37.54-06:00</Column>
  <Column id="26" name="ServerName">.</Column>
  <Column id="30" name="State">1</Column>
  <Column id="50" name="XactSequence">236223201284</Column>
  <Column id="3" name="DatabaseID">9</Column>
  <Column id="11" name="LoginName">fse</Column>
  <Column id="35" name="DatabaseName">ACS</Column>
  <Column id="51" name="EventSequence">167068</Column>
</Event>

DTCTransaction事件中的EventSubClass 16表示“事务正在中止”。

3个回答

9
为了延长超时时间,默认情况下最长为10分钟,如果未指定,则需要在目标系统上更新C:\ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ CONFIG \ Machine.config(如果您正在运行64位操作系统,请查看C:\ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ CONFIG)。将此添加为根级别的最后一项:
<system.transactions>
    <machineSettings maxTimeout="23:00:00"/>
</system.transactions>

例如,这将把超时时间设置为23小时。

实际值可在System.Transactions.TransactionManager.MaximumTimeout中查看。


2
我现在遇到了这个问题。哈!我只想补充一下,这个最大超时时间只能在 machine.config 中设置 - 你不能在 app.config 中覆盖它。如果你不被允许修改目标部署平台的 machine.config,这是一个真正的限制。 - Yoopergeek
是的,这似乎是设计上的问题...但我同意你的观点,当你无法更新服务器时,这并不好笑。 - Bongo Sharp

2
这可能是SqlConnection超时而不是分布式事务超时吗?
更新1
您可以使用SQL Server Profiler尝试监视意外连接断开。您只需确保将跟踪配置文件调整为仅包括您需要监视的事件,因为其输出可能非常冗长。我建议先仅监视“安全审计”事件类别下的“审核登录”和“审核注销”事件。
如果您在除独立/仅供自己使用的SQL Server实例之外的任何地方进行分析,则可能需要应用过滤器,以便仅显示来自您主机的事件。
您可能希望在连接字符串中明确指定超时值 - 将其设置得非常低,并查看是否更快地出现相同的行为。
更新2
从您的跟踪日志中,我看到两个异常,其详细信息为:
  • 错误:1222,严重性:16,状态:18
  • 错误:8525,严重性:16,状态:1

搜索 1222 异常的结果显示 http://www.sqlservercentral.com/Forums/Topic579864-146-1.aspx#bm645422,其中提到:

这个错误意味着在 msdb 中请求锁定并超时。通常,这意味着是在大型临时表或大型排序上进行的大型事务或类似事物。

你是否有任何可能与之相关的长时间运行的查询?也许是一个繁重的报告或类似的东西?

希望这能让你更进一步。


我该如何确定这个问题 -- 是否有一些跟踪工具可以用来追踪超时? - BlueMonkMN
我已经尝试使用SQL Server Profiler来监视事务事件和错误,但似乎并没有什么帮助。我没有看到超时的提及。也许我只是监视了错误的事件? - BlueMonkMN
我有一个长时间运行的查询... 我想弄清楚的是如何让它继续运行。 - BlueMonkMN
实际上我不是有一个长时间运行的查询,而是在同一事务中有很多操作。 - BlueMonkMN
我一直在徒劳地搜索,现在已经精疲力尽了...或许可以在你的问题上设置赏金,以吸引更好的回答? - Yoopergeek
终于搞定了。在下面发布了一个单独的答案。 - BlueMonkMN

2
这对于每个人来说可能都很明显,只有我不知道,但我刚刚遇到了这个问题,并想提一下我是如何解决的。尽管我修改了BlueMonkMN指示的位置的文件,但我仍然收到了默认的10分钟事务超时。由于我正在运行Windows 7 64位,因此.NET的machine.config文件位置位于以下位置:C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG 请注意,“Framework64”文件夹与上面的不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接