1

以下代码库在 Windows Server、Windows XP 上工作了多年,但在 Windows 7 上变得不可靠。

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

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

分布式事务完成。在新事务或 NULL 事务中登记此会话

在某些配置中,事务非常慢,并且很容易超过 60 秒的持续时间。

该错误看起来像是事务超时,或者可能SetComplete是在设置完成位的嫌疑人之后停用了组件。但是,它不是事务的根组件,并且该文档明确指出“但是,除非调用 SetAbort 的对象是事务的根,否则即使没有任何东西可以将其从最终中止中拯救出来,事务也会继续运行。该文档说“在事务的根对象停用之前,事务既不会提交也不会中止。 ”所以我不确定是否SetComplete会以某种方式导致错误。

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

我不明白我所看到的几个方面。

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

1 回答 1

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));
于 2013-02-08T10:09:06.137 回答