关于触发器使用链接服务器的问题处理

本文介绍了解决SQL触发器在执行UPDATE操作时遇到的分布式事务问题的方法,包括启动MSDTC服务、设置XACT_ABORT选项及调整MSDTC配置等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


上一篇 / 下一篇  2009-10-12 10:59:41 / 个人分类:实践

 

一、   问题现象:

在一个test 表上创建触发器如下:

ALTER TRIGGER [TR_test_I]

   ON   [dbo]. [ test ]

   AFTERINSERT , UPDATE

AS

BEGIN

IF   EXISTS( SELECT *FROM myTest. test. DBO. testWHERE MM_SNUMB= RTRIM ( @MM_SNUMB))

        BEGIN

          DELETE FROM myTest. test. DBO. testWHERE MM_SNUMB= RTRIM ( @MM_SNUMB)

        END

      INSERT INTO myTest. test. DBO. test  SELECT *FROM INSERTED

END

当对表test 进行UPDATE 操作时出现如下错误:
[OLE/DB provider returned message: 新事务不能登记到指定的事务处理器中。 ]

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

消息 7391 ,级别 16 ,状态 1 ,过程 TR_test_I ,第 26

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

二、   解决方案

根据网上查的资料进行了如下操作:

1.   双方启动MSDTC 服务
MSDTC
服务提供分布式事务服务,如果要在数据库 中使用分布式事务,必须在参与的双方服务器启动MSDTCDistributed Transaction Coordinator )服务。

2.   在事务开始前加入set XACT_ABORT ON 语句
对于大多数OLE DB 提供程序(包括SQL Server ),必须将隐式或显示事务中的数据修改语句中的XACT_ABORT 设置为ON 。唯一不需要该选项的情况是在提供程序支持嵌套事务时。

3.   MSDTC 设置
打开 管理 工具―― 组件服务 ,以此打开 组件服务―― 计算机 ,在 我的电脑 上点击右键。在MSDTC 选项卡中,点击 安全配置 按钮。在安全配置窗口中做如下设置:

1)   选中 网络DTC 访问

2)   在事务管理通讯中设置时,事务发起服务器选 允许出站“,
事务处理服务器选 允许入站 ,都选择 不要求进行验证

3)   选中启用XA 事务

4)   保证DTC 登陆账户为:NT   Authority/NetworkService

4.   确定后自动重启MSDTC 服务

5.   重新执行对test 表的UPDATE 操作,执行成功。

三、   进一步实验

上面的方法是通过“SQLOLEDB “,创建链接服务器来进行的。

之后,我有尝试使用ODBC 创建链接服务器进行测试 时也是经过了一番波折。

1.   创建链接服务器:
EXEC     sp_addlinkedserver 'mytest' , '' , 'MSDASQL' , 'test'

GO
EXEC sp_addlinkedsrvlogin   ' myte' , false, 'sa' , 'sa'
GO

2.   建立用户 DSN

3.   执行 test 表的UPDATE 操作时,产生如下错误:

[OLE/DB provider returned message: [Microsoft][ODBC 驱动程序管理器 ] 未发现数据源名称并且未指定默认驱动程序 ]

OLE DB error trace [OLE/DB Provider 'MSDASQL' IDBInitialize::Initialize returned 0x80004005:   ].

消息 7399 ,级别 16 ,状态 1 ,过程 TR_MOLD_MASTER_I ,第 26

OLE DB provider 'MSDASQL' reported an error.  

4.   经过多次调整链接参数后仍无法解决,无奈之下只好删除该 DSN, 创建了一个与之同样设置的系统 DSN ,进行测试时,经过一个较为漫长的等待后竟然成功了 ( 真是太让人惊讶了 )
注: 与用户 DSN 不同的是系统 DSN 允许所有登录服务器的用户使用

四、   总结:

经过一番折腾,触发器终于如愿正常使用了。通过比较网上针对此类问题的其它说明,我个人认为其中的部分内容并非引起该问题的原因,在设置时是可有可无的。

1. 开始时填写的 BEGIN   DISTRIBUTED   TRANSACTION COMMIT TRANS

2. MSDTC 设置时的客户端和远程访问,事务管理通讯中的允许入站或出站 ( 虽然自己没有尝试了解进一步的原因,但个人认为不了解的东西使用的越少越好 )

3. 链接服务器远侧域名解析, 135 端口等,在 MSDTC 服务启用的情况下,此类问题都可以不去考虑

但是,其中的有些细节是必须注意的,如 :

SET ON 改为 OFF 时,会产生如下错误:

[OLE/DB provider returned message: 无法在此会话中启动更多的事务。 ]

OLE DB error trace [OLE/DB Provider 'SQLOLEDB' ITransactionLocal::StartTransaction returned 0x8004d013:  ISOLEVEL=4096].

消息 7395 ,级别 16 ,状态 2 ,过程 TR_MOLD_MASTER_I ,第 28

Unable to start a nested transaction for OLE DB provider 'SQLOLEDB'.  A nested transaction was required because the XACT_ABORT option was set to OFF.

缺少该语句时,也会产生同样的错误。

不管如何,上面的内容只是自己在现有的环境下测试得出的结果,并不保证其它的环境同样适用。希望能给大家帮助。

 

最后添加一个微软 的DTC测试工具http://space.itpub.net/?uid-672726-action-viewspace-itemid-616306

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值