SQL本地与Azure实例链接服务器偶发“无活动事务”错误排查问询
根因定位
针对描述的偶发DTC分布式事务报错、单向链接服务器不通后自动恢复的现象,根因按优先级排序如下:
- SQL Server 2012 SP1 已知DTC兼容性BUG:该版本存在分布式事务上下文同步失败的已知问题,当跨版本(SQL 2012 <-> SQL 2019)发起分布式事务时,偶发出现事务上下文无法被对方实例识别的情况,且不会写入常规SQL日志。
- NetBIOS名称缓存过期失效:依赖hosts+lmhosts做名称解析时,Windows的NetBIOS名称缓存默认存在10分钟的TTL,缓存过期时如果刚好遇到网络抖动导致lmhosts解析临时失败,会出现DTC无法找到对方节点的情况,缓存自动刷新后问题恢复。
- DTC RPC会话超时:跨VPN的长连接如果超过防火墙/操作系统的默认TCP idle超时时间(Azure默认是4分钟,本地Windows默认是2小时),会被中间设备静默断开,导致DTC会话中断,新会话建立前出现单向不通的问题。
- 临时端口耗尽:MSSQL-Accounts作为被调用方,当分布式事务并发量较高时,动态端口范围被占满,无法为新的DTC/RPC请求分配端口,端口自动释放后恢复正常。
解决方案
按实施优先级排序:
- 修复SQL 2012版本BUG:将MSSQL-Accounts的SQL 2012升级到SP4 + 最新累计更新包,微软官方已经在后续补丁中修复了跨版本DTC事务同步的相关问题。
- 固定DTC通信端口,优化解析配置:
- 分别在两台服务器的DTC配置中指定固定通信端口,避免动态端口分配失败的问题
- 在两台服务器的
hosts文件中添加记录后,执行ipconfig /flushdns和nbtstat -R清空缓存,同时将NetBIOS节点类型设置为P节点(仅用lmhosts解析,禁用广播)
- 优化TCP超时配置:
- 在Azure端的VM网卡配置中,将TCP idle超时时间调整为30分钟
- 在两台服务器的注册表路径
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters下添加KeepAliveTime值为30000(30秒发送一次保活包),避免长连接被中间设备断开
- 扩大动态端口范围:在两台服务器上执行命令
netsh int ipv4 set dynamicport tcp start=10000 num=50000,扩大RPC/DTC可用的动态端口范围,避免端口耗尽问题 - 新增DTC日志记录:开启DTC的跟踪日志(组件服务->我的计算机->分布式事务协调器->本地DTC->属性->跟踪->勾选所有跟踪选项),后续再出现问题可直接通过DTC跟踪日志定位具体失败节点。
内容的提问来源于stack exchange,提问作者MagicalArmchair
相关产品推荐
相关产品推荐

