触发器双向同步时的疑问!!!(即客户端和服务器数据要实时同步),100分开始散分了

HenanBoy 2009-03-09 07:03:47
问题描述:
1.以下代码能够利用链接服务器,实现客户端访问服务器,且是正常的
2.在客户端上增加了三个触发器,即增删改,实现了客户端增删改的同时,服务器中的相关表也正常增删改。
3.但用同样的方法,在服务器上建立了链接服务器后,在服务器上建立触发器时,提示这样的错误:

服务器: 消息 7399,级别 16,状态 1,过程 tr_insert_testClient,行 5
OLE DB 提供程序 'MSDASQL' 报错。
[OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server]分布式事务已完成。请将此会话登记到新事务或 NULL 事务中。]
[OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server]该操作未能执行,因为 OLE DB 提供程序 'MSDASQL' 无法启动分布式事务。]
[OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server]OLE DB 错误跟踪[OLE/DB Provider 'MSDASQL' ITransactionJoin::JoinTransaction returned 0x8004d00a]。]
[OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server][OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server]其它会话正在使用事务的上下文。]]
OLE DB 错误跟踪[OLE/DB Provider 'MSDASQL' IRowsetChange::InsertRow returned 0x80004005: ]。

详细代码如下:

客户端详细测试:
--客户端和服务器端表分别为testClient,testServer,表结构一样,如下:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[testClient]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[testClient]
GO

CREATE TABLE [dbo].[testClient] (
[id] [int] NOT NULL ,
[email] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO

--测试远程链接服务器
EXEC sp_addlinkedserver
'xiaowang',
'',
'MSDASQL',
NULL,
NULL,
'DRIVER={SQL Server};SERVER=xiaowang;UID=sa;PWD=sa;'
go

EXEC sp_addlinkedsrvlogin @rmtsrvname='xiaowang',@useself='false',@locallogin='sa',@rmtuser='sa',@rmtpassword='sa'

--测试分布式事务
--客户端和服务器端同时开启分布式事务处理服务,开启方法为:
--我的电脑--控制面板--管理工具--服务--右键 Distributed Transaction Coordinator--属性--启动--并将启动类型设置为自动启动
--go
set XACT_ABORT on
set ANSI_NULL_DFLT_ON on
set ANSI_WARNINGS on

BEGIN DISTRIBUTED TRANSACTION
select * from xiaowang.pubs.dbo.testServer
commit tran


--用触发器测试同步流程
--1。客户端上触发器
--新增同步
create trigger tr_insert_testClient on testClient
for insert
as
set xact_abort on
insert xiaowang.pubs.dbo.testServer(id,email)
select id,email from inserted
go

--测试插入触发器
insert into testClient(id,email) values('21','dfdsf')

--查看触发器状态
EXEC sp_helptrigger testClient

--删除同步
create trigger tr_delete_testClient on testClient
for delete
as
set xact_abort on
delete b
from xiaowang.pubs.dbo.testServer b,deleted d
where b.id=d.id
go

--修改同步
create trigger tr_update_testClient on testClient
for update
as
set xact_abort on
update a set id=b.id,email=b.email
from xiaowang.pubs.dbo.testServer a,inserted b
where a.id=b.id
go


--上面可以实现从客户端到服务器的同步,测试全部正常


--但在服务器上进行以上类似的操作时,却提示错误,在服务器上操作如下:
EXEC sp_addlinkedserver
'mfmdl',
'',
'MSDASQL',
NULL,
NULL,
'DRIVER={SQL Server};SERVER=mfmdl;UID=sa;PWD=sa;'
go

EXEC sp_addlinkedsrvlogin @rmtsrvname='mfmdl',@useself='false',@locallogin='sa',@rmtuser='sa',@rmtpassword='sa'

--此时是正常的
select * from mfmdl.pubs.dbo.testClient

--在服务器端创建触发器
create trigger tr_insert_testServer on testServer
for insert
as
set xact_abort on
insert mfmdl.pubs.dbo.testClient(id,email)
select id,email from inserted
go

--此时随便插入一条语句时,报错

insert into testServer(id,email) values('3454','dfsdf')

/*
服务器: 消息 7399,级别 16,状态 1,过程 tr_insert_testClient,行 5
OLE DB 提供程序 'MSDASQL' 报错。
[OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server]分布式事务已完成。请将此会话登记到新事务或 NULL 事务中。]
[OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server]该操作未能执行,因为 OLE DB 提供程序 'MSDASQL' 无法启动分布式事务。]
[OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server]OLE DB 错误跟踪[OLE/DB Provider 'MSDASQL' ITransactionJoin::JoinTransaction returned 0x8004d00a]。]
[OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server][OLE/DB provider returned message: [Microsoft][ODBC SQL Server Driver][SQL Server]其它会话正在使用事务的上下文。]]
OLE DB 错误跟踪[OLE/DB Provider 'MSDASQL' IRowsetChange::InsertRow returned 0x80004005: ]。
*/

环境测试:xp+sql2000(sp4),两机环境一样。
急盼哪位兄弟能指点一下,分不够再加!!!!!!上面的环境可直接拷贝测试
...全文
142 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
mfm11111 2009-03-14
  • 打赏
  • 举报
回复
这很容易的,方案我给你发过去
HenanBoy 2009-03-09
  • 打赏
  • 举报
回复
to jinjazz,呵呵,明白了,分布式不支持环回,我刚才分析了一下,我这种情况就是环回。
如果是这样,根据我的需求,我能否把它做成面向服务的架构,比如:现在有六个系统,我用webservice搭一个架构,然后放在iis上,然后里面放一些对cs或bs端数据的处理,这种情况如果用来做同步,是否会方便?这种架构是否属于分布式的架构。
jinjazz 2009-03-09
  • 打赏
  • 举报
回复
这个问题一直存在,这样的同步是山寨版的,不适合实际应用 ,一台机器开启事务后提交或者回滚,就触发器而言另外一台机器无法做同样的事务。
HenanBoy 2009-03-09
  • 打赏
  • 举报
回复
to jinjazz,上面我发布的问题,是否在sql2000中本身就存在这样的问题,如果是这样,其它人用触发器实现双向同步又是如何做到的,在不改变表结构的情况下
jinjazz 2009-03-09
  • 打赏
  • 举报
回复
如果都是sqlserver,你可以尝试订阅发布
http://msdn.microsoft.com/zh-cn/library/ms151170.aspx
HenanBoy 2009-03-09
  • 打赏
  • 举报
回复
to jinjazz,我能否这样做?
在客户端还是做触发器,只是说触发的同时,通过程序连服务器,然后再在服务器端进行操作。
现在我这边的需求是这样的:
有六个不同的系统,有cs端的和bs端的,且有两个bs端的系统不是我们公司开发的,这样如果在服务器端进行程序操作,就意味着还要在其它系统中都进行增删改的操作,那样的话工作量是非常大的,而且一般的系统都是封装好的,即使在服务器端用程序操作,也不太现实。不知道还有没好的方法能进行实时同步呢,谢谢了
benjaminwu198818 2009-03-09
  • 打赏
  • 举报
回复
接分…谢谢。。。学习
jinjazz 2009-03-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 HenanBoy 的回复:]
to jinjazz :如果自己写同步程序,怎么样在不改变表结构的基础上做才能实时同步?
[/Quote]

不改表结构还得依靠触发器,只是触发的本服务器,然后通过程序传送到其他服务器
HenanBoy 2009-03-09
  • 打赏
  • 举报
回复
to jinjazz :如果自己写同步程序,怎么样在不改变表结构的基础上做才能实时同步?
jinjazz 2009-03-09
  • 打赏
  • 举报
回复
不要再链接服务器上做触发器,事务在分布式应用中会有问题的,非要这么做,自己写同步程序,或者用sql的订阅复制功能
stonehy520 2009-03-09
  • 打赏
  • 举报
回复
不是吧,你每个客户端都有临时库?
没这样做过,帮顶
HenanBoy 2009-03-09
  • 打赏
  • 举报
回复
上面的代码直接拷就可运行,只不过客户端和服务器的名称分别改为mfmdl,xiaowang即可,有条件的兄弟帮忙测一下,结果发上来就有分
HenanBoy 2009-03-09
  • 打赏
  • 举报
回复
也就是说,如果在客户端的某一张表中做了一个触发器,那么当在服务器中按同样的方式做一个触发器时,就报上面的错。哪位兄弟遇到过这个问题的,高分相谢!
wangzhenyue 2009-03-09
  • 打赏
  • 举报
回复
!!看不懂。。来接分了。。不好意思
天乐_那由他 2009-03-09
  • 打赏
  • 举报
回复
来接分了,顺便帮顶,坐等高手

62,267

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧