触发器+linked server同步易出错,主因是跨实例事务不一致、rpc out未开启、数据类型不匹配及缺乏异常处理。必须启用rpc out、用try...catch捕获错误、显式转换字段、跳过特殊列,并添加超时、日志和幂等校验。

触发器 + Linked Server 同步为什么容易出错
直接在源表上建 INSERT/UPDATE/DELETE 触发器,再通过 MJZFPT 这类链接服务器写目标库,看似实时,实则埋雷。最常见的是事务跨实例失败导致源端回滚、目标端没写入,或反过来——目标库不可用时源表被锁死。SQL Server 不支持跨实例的分布式事务自动回滚(除非显式启用 MSDTC 且配置极严),而多数生产环境禁用 MSDTC。
触发器里调用链接服务器必须加 TRY...CATCH
哪怕只是简单 INSERT INTO MJZFPT.DB_ZF.dbo.T_ZF ...,也得包裹异常处理。否则一次网络抖动或目标库权限变更,整个触发器执行失败,源表操作就卡住。
-
TRY块里执行远程写入,成功则RETURN -
CATCH块里记录错误到本地日志表(不要写远程!),并用RAISERROR抛出可控提示,避免静默失败 - 避免在触发器里做复杂逻辑或查远程表——性能差、锁等待长、死锁风险高
Linked Server 的 rpc out 必须显式开启
很多团队只配了 sp_addlinkedserver 和 sp_addlinkedsrvlogin,却漏掉这句:
EXEC sp_serveroption 'MJZFPT', 'rpc out', 'true'
没开 rpc out,触发器里任何带参数的远程存储过程调用(比如 EXEC MJZFPT.DB_ZF.dbo.sp_sync_log @id)都会报错:Msg 7411, Level 16, State 1, Line X Server 'MJZFPT' is not configured for RPC. 即使只是 INSERT,某些驱动版本也会隐式触发 RPC 检查。
字段映射和数据类型不一致是同步失败主因
源表 T_ZF.C_XM 是 nvarchar(50),目标表同名字段却是 varchar(30)?触发器一执行就截断或报错。更隐蔽的是时间类型:datetime 和 datetime2 在跨库比较时可能因精度差异导致 NOT MATCHED 判断失准。
- 同步前用
SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM MJZFPT.INFORMATION_SCHEMA.COLUMNS对比两边结构 - 所有插入值强制显式转换,例如
CONVERT(nvarchar(50), S.C_XM),别依赖隐式转换 - 对
IDENTITY列、计算列、默认约束等特殊字段,触发器里要跳过或重置
真正难的不是写通第一行触发器,而是让这套机制在连续跑三个月后仍不丢数据、不锁表、不因某次凌晨网络波动就停摆。每加一个远程写入点,都要多一道超时控制、一次日志落盘、一次幂等校验——这些不在语法里,但在生产里缺一不可。










