`SetComplete`反模式停止在Windows 7上运行

时间:2013-02-01 23:07:21

标签: windows windows-7 transactions timeout com+

以下代码库在Windows Server,Windows XP上运行了多年,在Windows 7上变得不可靠。

两个COM +组件(调用者和被调用者)共享相同的事务上下文并参与间接递归。调用者最初多次调用被调用者,并且被调用者在返回之前总是最终调用SetCompleteSetAbort(无论这是调用者 - > Callee调用,还是Caller-> Callee- >呼叫者>被叫方)

我看到第二次调用被调用者的第一个SQL查询出错了:

  

分布式事务已完成。在新事务或NULL事务

中登记此会话

在某些配置中,交易非常缓慢,并且很容易超过60秒。

错误看起来像事务超时,或者可能是在设置完成位的嫌疑人SetComplete之后停用组件。但是,它不是事务的根组件,this documentation具体说“但是,除非调用SetAbort的对象是事务的根,否则事务继续运行,即使最终没有任何东西可以保存它中止。This documentation说“事务既未提交也未中止,直到事务的根对象停用。”所以我不确定SetComplete是否可能以某种方式导致错误

在安装时所有组件的组件级别的事务超时设置为1800秒,全局事务超时设置为60秒。组件主要使用ADO(包括断开连接的结果集)或.NET SqlClient进行数据库访问。

我不了解我所看到的几个方面。

  1. 如果同一事件中同一组件的多个实例同时处于活动状态,SetComplete是否会导致除调用SetComplete之外的任何实例的早期停用,或影响应用规则交易超时?
  2. Windows 7是否以与其他几个操作系统不同(更快)的方式停用组件?是否有任何配置可以控制此行为。
  3. Windows 7是否可能忽略组件级事务超时?存在此类缺陷long ago

1 个答案:

答案 0 :(得分:0)

我很乐意将赏金奖励给任何能够对所提问题提供任何好的见解的人。但是,我们最初的问题被追溯到了这一点。

我们发现一个特别长的运行事务几乎可以保证花费超过60秒(由于不幸的同步和重试逻辑)。与其他代码库不同,它的事务上下文是手动创建的,并且在Windows 7上继承了全局事务超时,即使在组件内执行所有这些都将声明性事务时间设置为1800秒。为什么这仍然适用于其他操作系统还不是很清楚,但当然我们正在摆脱这个长期运行的交易场景。

这就是“手动创建”的含义。

_COM_SMARTPTR_TYPEDEF(ITransactionContextEx, __uuidof(ITransactionContextEx));
ITransactionContextExPtr pTransContext;
TESTHR(pTransContext.CreateInstance(CLSID_TransactionContextEx));

ISomeSvcsPtr pSomeSvcs;

pTransContext->CreateInstance(__uuidof(PSSomeSvcs), 
                              ISomeSvcsPtr::GetIID(), 
                              reinterpret_cast<void **>(&pSomeSvcs));