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