环境:windows server 2003 SP2 + mssql 2000 SP4
最近在开发一个报表查询系统,使用到链接数据库技术,由于第一次接触该技术,所以在开发的过程中遇到了重重困难,幸好有百度,幸好有热心的同事,问题也如愿以偿的解决了。
在整个开发过程中使用了两种链接技术:
1.ODBC链接方式
--建立链接服务器
EXEC sp_addlinkedserver 'remote_queueRpt','','MSDASQL',NULL,NULL,'DRIVER={SQL Server}; SERVER=192.168.1.103; UID=sa; PWD=sa; '
--建立链接服务器登陆映射
exec sp_addlinkedsrvlogin @rmtsrvname='remote_queueRpt',@useself='false',@locallogin='sa',@rmtuser='sa',@rmtpassword='sa'
go
2.OLEDB链接方式
exec sp_addlinkedserver 'remote_queueRpt','','sqloledb','192.168.1.112'
exec sp_addlinkedsrvlogin 'remote_queueRpt','false',null,'sa','sa'
go
注:经测试,发现第二种方式速度上要快很多,所以强烈推荐使用OLEDB链接方式。
好了,链接服务器已经建立成功,下面是我要执行的存储过程,用到了异步事务
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
ALTER PROCEDURE wy_UpLoad AS
SET XACT_ABORT ON --这句话很重要
BEGIN DISTRIBUTED TRAN --开始异步事务
Declare @mac_id varchar(48)
set @mac_id=N'00-25-64-58-18-10'
---如果存在该网卡号,则继续执行语句,否则语句为空
IF exists (select DiskNumber from remote_queueRpt.Wy_Report.dbo.Region WHERE DiskNumber=@mac_id)
Begin
--上传排队数据
INSERT INTO remote_queueRpt.Wy_Report.dbo.History_002564581810 (getTicketTime,
YW_ID,YW,Num ,caption,gh,id,opertime,window_no,totaltime,
Approx_awaiting,mac_id,user_name,finsh_time,num_id) SELECT GetTicketTime,
YW_ID,YW,Num ,caption,gh,id,opertime,window_no,totaltime,
Approx_awaiting,@mac_id,user_name,finsh_time,num_id FROM wy_tmp
IF @@ERROR<>0 GOTO QuitWithRollBack
DElETE FROM wy_tmp
IF @@ERROR<>0 GOTO QuitWithRollBack
--上传评价数据
INSERT INTO remote_queueRpt.Wy_Report.dbo.opinion_002564581810 (id,
numid,num,gh ,user_name,service_level,operator_time,opinion,window_no,mac_id)
SELECT id,numid,num,gh ,user_name,service_level,operator_time,opinion,window_no,@mac_id
From wy_opiniontmp
IF @@ERROR<>0 GOTO QuitWithRollBack
DElETE FROM wy_opiniontmp
IF @@ERROR<>0 GOTO QuitWithRollBack
--上传登录日志
INSERT INTO remote_queueRpt.Wy_Report.dbo.loginlog_002564581810 (gh,
user_name,window_no,info ,logtime,id,mac_id)
SELECT gh,user_name,window_no,info ,logtime,id,@mac_id
From wy_loginlog
IF @@ERROR<>0 GOTO QuitWithRollBack
DElETE FROM wy_loginlog
IF @@ERROR<>0 GOTO QuitWithRollBack
COMMIT TRAN
GoTo EndSave
QuitWithRollback:
Rollback TRANSACTION
EndSave:
Print '1'
End
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
存储过程创建好了,下一步要执行该存储过程来发送数据了
EXEC wy_UpLoad
该语句执行了近一分钟后,终于执行完毕,结果肯定没那么顺利,会弹出错误信息如下图所示:
服务器:消息7931,级别16,状态1,行5
该操作未能执行,因为OLE DB提供程序'sqloledb'无法启动分布式事务
[OLE/DB provider returned message:新事务不能等级到指定的事务处理器中]
OLE DB 错误跟踪[OLE/DB Provider 'sqloledb' ITransactionJoin::JoinTransaction returned 0x8004d00a]
问题出现了,百度查询后进行了如下设置:
启用网络DTC是分布式数据库事物控制的必要条件。设置过程应依下面步骤进行。
1) 单击“开始”,指向“控制面板”,然后单击“添加或删除程序”;
2) 单击“添加/删除 Windows 组件”;
3) 选择“应用程序服务器”,然后单击“详细信息”;
4) 选择“启用网络 DTC 访问”, 网络管理 、网络事务、XA 事务。另外,DTC 登录帐户一定要设置为“NT Authority\NetworkService”,并且事务管理器通讯不要求进行验证。然后单击“确定”;
5) 单击“下一步”;
6) 单击“完成”;
7) 停止分布式事务处理协调器服务,然后重新予以启动;
8) 停止 Microsoft SQL Server 和其他参与分布式事务处理的资源管理器服务(如 Microsoft 消息队列),然后将其重新启动。
二、Windows xp配置MSDTC的方法
控制面板-----〉管理工具-----〉组件服务
选择组件服务-----〉计算机--------〉我的电脑,再点击鼠标右键。
“点击安全性配置(I)….”按钮,选择项如下:
注:设置成功之后应重启MSDTC服务,之后再重启数据服务,注意先后顺序。
本以为大功即将告成,但执行存储过程之后问题依旧,继续Baidu,将会有以下的解决方案
启动RPC服务, 该服务应该是默认启动吧?排除
开启135端口并设为例外(防火墙设置),
C:\windows\system32\Driver\etc\Host 进行ip和域名映射之类的
以下是删除链接服务器登录映射和链接服务器:
exec sp_droplinkedsrvlogin 'remote_queueRpt' ,'sa'
exec sp_dropserver 'remote_queueRpt'