Never give up - LEO

人 只有在合适的地方 才能体现出最大的价值
  博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

分布式查询

Posted on 2007-08-28 15:24  lizhiwen  阅读(4551)  评论(2编辑  收藏  举报
 

前几天做一个分布式查询遇到了一些问题(问题详细描叙见:http://www.cnblogs.com/lizhiwen/archive/2007/08/24/868141.html)

经过反复查找,总算是找到了问题所在。下面就说一下大致过程:

环境:

服务器Service AService BService A安装的win2003Service B 安装的win xp sp3

两台服务器都是装的sql server 2000, A B在同一个局域网内.

有两个存储过程ProcAProcB,存储过程都在Service A上,其中ProcB中有查询Service B数据库中表数据语句(只有查询操作)

 

一、创建分布式存储过程

如果之前Service A没有连接过Service B,那么创建Proc B时会提示如下错误:

 

Could not find server 'Service B' in sysservers. Execute sp_addlinkedserver to add the server to sysservers.

 

这是提示你首先在ServiceA中创建一个ServiceB的连接。使用sql 语句,如下

 

USE   master  

GO  

EXEC  sp_addlinkedserver   'Service B',N'SQL Server'  

GO  

EXEC  sp_addlinkedsrvlogin   'Service B',   'false',   NULL,   '用户名',   '密码'

 

运行完上面的语句后,再创建Proc B,这时又出现了另外一个错误:

 

---------------------------

Microsoft SQL-DMO (ODBC SQLState: 42000)

---------------------------

Error 7405: Heterogeneous queries require the ANSI_NULLS and ANSI_WARNINGS options to be set for the connection. This ensures consistent query semantics. Enable these options and then reissue your query.

---------------------------

OK  

---------------------------

原来设置用于分布式查询的 SQL-92 选项,必须先将连接的 ANSI_NULLS ANSI_WARNINGS 选项打开,然后才能执行分布式查询。如下:

Set ANSI_NULLS ON

Set ANSI_WARNINGS ON

Create procedure ProcB

……

这样分布式查询的存储过程就创建好了。该存储过程只能在查询分析器中创建。

二、测试存储过程

开始测试存储过程,先单独测试ProcB,第一次没有通过,报找不到数据库。原来是Service B的防火墙打开了,把防火墙关掉后,再运行ProcB,结果正常,测试通过。

再运行ProcA,又出问题了,报一个这样的错误:

The operation could not be performed because the OLE DB provider 'SQLOLEDB' was unable to begin a distributed transaction.

[OLE/DB provider returned message: New transaction cannot enlist in the specified transaction coordinator. ]

OLE DB error trace [OLE/DB Provider 'SQLOLEDB' ITransactionJoin::JoinTransaction returned 0x8004d00a].

经过从网上查找和反复测试,终于发现了问题所在。问题出在了分布式事务上面。

l         当单独运行ProcB时,只是简单的查询,所以不会打开分布式事务。

l         当去掉ProcA中的Insert语句也能成功,原因是这样也不会打开分布式事务。

l         而一用上Insert语句,就必须打开分布式事务,而这时ServiceB并不支持分布式事务,所以报出了上面的错误。

这时就必须对ServiceB进行一些设置:

1.      虽然关掉了防火墙,但是还必须把分布式程序和端口加上。具体操作:

在防火墙操作界面有一个Add program按钮,点击该按钮添加C:\WINDOWS\system32\msdtc.exe文件;然后再点击 Add Port按钮,添加135端口。

2.      打开 Control Panel - Administrative Tools--Component Services,  在打开的窗口中选择Component Services—computer – my computer. 然后再my computer上点击右键选properties, 在弹出的对话框中选标签头MSTDC---Security Configuration,按照如下进行勾选:


然后点击确定,再重启分布式事务服务,再运行
ProcAOK了。

 

到这基本上就OK了,由于没时间,我只是在win xp中测试过,不知道在其他系统会怎么样,还请各位赐教,谢谢!