当不小心启用分散式事务机制时,且环境设定不允许时,就会产生【已停用分散式事务管理员 (MSDTC) 的网络存取。请使用组件服务系统管理工具启用 DTC,以使用 MSDTC 安全性设定中的网络存取】错误消息,此时可以透过?new TransactionScope(TransactionScopeOption.Suppress)
排除不需要纳入事务的部分,避免分散事务的情境产生。
前言
当操作不同 DB 服务器且需要在同一个事务下完成,就需要使用分散式事务(Distributed Transaction)来完成;在微软平台上 MSDTC (Distributed Transaction Coordinator)?是用来协调不同 DB 在单一事务下完成所有行为,但有时候我们不是真的需要这个功能,而是不小心启用这个机制,且环境设定不允许时,就会产生【已停用分散式事务管理员 (MSDTC) 的网络存取。请使用组件服务系统管理工具启用 DTC,以使用 MSDTC 安全性设定中的网络存取】错误消息,而这时候要怎样来排除呢? 请看以下实际的例子。
实例
目前系统使用两台 DB 做分流,一台 read / write 都可以,另外一台 read only 做数据查询使用;当执行功能时,需对数据库进行一连串的数据异动行为 (connect to read / write db),同时需要取出相关数据做参考 (connect to read only db),且为了确保所有异动在同一个事务完成,会将所有逻辑包在 transaction scope 中。
发生错误
程序执行下去就报错,错误消息表示目前服务器的设定并未启用 DTC 功能,因此若使用到分散式事务的机制就会产生该错误。
System.Transactions.TransactionManagerCommunicationException: 已停用分散式事务管理员 (MSDTC) 的网络存取。请使用组件服务系统管理工具启用 DTC,以使用 MSDTC 安全性设定中的网络存取。 ---> System.Runtime.InteropServices.COMException: 事务管理员已经停用了对远端/网络事务的支持。 (发生例外状况于 HRESULT: 0x8004D024)
错误排除
面对此案例来说,由于连线到 read only DB 所做的行为本来就不需要列入 transaction 中 (不对数据进行异动,且跟此次事务异动行为无关),但偏偏该行为却又穿插在各个异动行为中,这时就可以透过 TransactionScopeOption.Suppress
参数将无须纳入事务的部分再用 TransactionScop 包起来,避免分散事务的情境产生。示意代码如下。
参考资讯
.NET分散式事务程序开发FAQ
希望此篇文章可以帮助到需要的人
若内容有误或有其他建议请不吝留言给笔者喔 !
原文:大专栏 [C#] 排除无须纳入交易的查询,避免产生不必要的分散式交易 (Distributed Transaction)