一次难忘的 MTS 故障的排除过程

我们一个客户的系统今天坏了。先大致介绍一下该系统的简单构成。
一个 web 服务器,一个数据库服务器。 数据库服务器是 SQL server 2000, 处在局域网里,中间有防火墙分隔,不能从外界直接访问。
web 服务器上是 Windows 2000 server, IIS 5.0, 跑的 ASP + COM+ 程序。

以前跑的好好的程序,这几天忽然出现以下的错误现象:
在某个页面, 一提交就要等很久才有响应,然后提示一个超时错误。以及下列提示:

Microsoft OLE DB Provider for SQL Server 错误 '8004d00a'

不能在指定的事务处理器中获得新事务。

或者

Microsoft OLE DB Provider for SQL Server 错误 '8004d00a'

新事务不能登记到指定的事务处理器中。

我查看了一下,这个页面是我原先对旧系统改造的时候做的。以前别人做的 ASP 程序在复杂的数据库操作时居然没有加事务。我用 MTS 的事务功能简单的加了事务控制。大致像下面这样,大家都熟悉的,不再罗嗦。

<%@ Transaction=Required %>
<%
做一些数据库操作
.
if 某个条件 then
 ObjectContext.SetAbort
else
 ObjectContext.SetComplete
end if

function OnTransactionAbort
    Response.Write("Transaction Aborted.")
end function


function OnTransactionCommit
    Response.Write("Transaction Commited.")
end function
%>

为了诊断,我首先写了一个最简单的页面,其中简单的打开数据库连接,然后 SetComplete. 结果发现失败。。
然后注释掉声明事务处理的所有代码,Response.Write conn.State 查看数据库连接的状态。发现能正确的输出 1, 说明连接数据库是没有问题的。
而我一旦加入开始那句 <%@ Transaction=Required %> 则会立马重现原先的那个错误。
至此可以断定是系统的 MTS 服务出了问题。可是具体什么问题呢?
google 搜索了一堆有丝毫联系的文章,最终看到这个 http://support.microsoft.com/default.aspx?scid=kb;zh-cn;329332 还算有点帮助。当我照着做的时候才发现原来这个问题讲得是 Windows server 2003, 在 windows 2000 上不存在文中说的那个选项。
郁闷,只好继续搜。看了一堆不太相干的国外论坛上的帖子,最终找到了:
http://support.microsoft.com/default.aspx?scid=kb;en-us;250367
文中提到,如果要使用 MTS 分布式事务,有一个前提条件是两台机器之间能够通过 NetBIOS 或者 DNS 解析对方的机器名。而这个能否解析可以通过 ping 命令来验证。
我立刻在 web 服务器上执行了
ping db
结果却不是预想的 192.168.2.5, 而是 211.99.193.150 , 一个 internet 上的 ip 地址。
但是奇怪的是,我
ping -a 192.168.2.5 能够正确地解析为 db
不管怎么说,现在基本上可以判断这就是问题的所在了。只要把那个错误的解析给去掉就应该可以了。

后面我修改了本机的 lmhosts 文件强行加入一行
192.168.2.5 db
并且
ipconfig /flushdns
nbtstat -r
都执行了之后还重启都没用。

最终 icuc88 (http://www.jaron.cn/inspiration/) 提醒我修改了 hosts 文件。 同样是加入这个地址映射。
然后 ping 成功解析之后,我赶紧打开 IE, 测试一下程序,
Everything is OK now !

(因为问题比较少见,暂放首页, 希望对遇到类似问题的人有帮助)

原文地址:https://www.cnblogs.com/RChen/p/115720.html