前言
最近在做.NET项目,使用的是SQLServer数据库,其中有个功能涉及到多数据源的操作,那么多数据源就要确保多个数据源之间数据的一致性,这里就用到了分布式事物。
问题产生
使用TransactionScope进行事务控制
//开启事物 using (TransactionScope scope = new TransactionScope()) { List<BatchProcessedEntity> batchProcessings = new List<BatchProcessedEntity>(); //将电子束的订单插入到电子束的数据源中 using (PMSEBEAMContext electronBeamContext = new PMSEBEAMContext()) using (PmsTestEntities pmsTestEntities = new PmsTestEntities()) using (PMSContext xRayContext = new PMSXRAYContext()) { //查询电子束数据库中订单信息 List<BatchProcessedEntity> electronBeamList = electronBeamContext.BatchProcessedEntity.ToList(); //放入集合中 batchProcessings.AddRange(electronBeamList); //从电子束数据库的数据源中删除 electronBeamContext.BatchProcessedEntity.RemoveRange(electronBeamList); electronBeamContext.SaveChanges(); //查询X射线数据库中订单信息 List<BatchProcessedEntity> xRayList = xRayContext.BatchProcessedEntity.ToList(); //放入集合中 batchProcessings.AddRange(xRayList); //从X射线数据库的数据源中删除 xRayContext.BatchProcessedEntity.RemoveRange(xRayList); xRayContext.SaveChanges(); //接收insert的受影响行数 int result = 0; //插入到pms库中 pmsTestEntities.BatchProcessedEntity.AddRange(batchProcessings); result = pmsTestEntities.SaveChanges(); //如果数据全部插入成功则返回true if (result == batchProcessings.Count) { //提交事物 scope.Complete(); return; } throw new Exception("数据库同步失败"); }
分布式事务(Distributed Transaction Coordinator)未开启原因
该伙伴事务管理器已经禁止了它对远程/网络事务的支持。
在使用 TransactionScope 进行分布式事务时,确保分布式事务管理器(DTC)已启用并在运行。检查操作系统中的服务列表,确保 “Distributed Transaction Coordinator” 服务正在运行。一般情况下这个服务时开启状态的,如果没有开启则通过控制面板——管理工具——组件服务——服务找到Distributed Transaction Coordinator服务将其启动
当然这些启动了还行,因为仅仅启动了服务,仍然会报该伙伴事务管理器已经禁止了它对远程/网络事务的支持的错误,这里还要做一步就是在组件服务——计算机——我的电脑——Distributed Transaction Coordinator这个层级下点击本地DTC鼠标右键属性
打开属性窗口后我们直接到点击安全进入这个页面将安全设置中的选项进行勾选,可以参照我这个。
至此这个错误就解决了。
System.Transactions.TransactionManagerCommunicationException: 与基础事务管理器的通信失败。
可以看一下错误,这里说的是分布式事务失败给出了几个原因,我这里在解决这个问题的过程中也找了很多相关的内容,大致上的思路都是开放端口、开放服务,我这里贴一两篇大家可以看一下
关于TransactionScope出错:“与基础事务管理器的通信失败”的解决方法
【MSDTC】与基础事务管理器的通信失败 .NET分布式开发报错:“与基础事务管理器的通信失败”的解决方法
关于这个错误其实还是防火墙的问题,本人这次碰到的就是因为Windows的防火墙和linux的防火墙不一样的就是Windows它还能对一些应用进行限制,也就是说不仅仅是端口的问题,这里如果你根据上面两个博客做了相应的配置以后仍然出现通信失败的问题,那么你不妨打开防火墙点击这个允许应用通过Windows Defender防火墙进行通信进入里面。找到分布式事务处理协调器这个选项,将后面的网络类型勾选上,最后点击确定就可以了。
重点:以上关于DTC的配置是需要数据库服务器和项目部署的服务器都要进行配置的。
.NET分布式事务为什么要数据库端和客户端都要开启DTC
在使用.NET分布式事务时,确保数据库端和客户端都开启DTC(分布式事务协调器)的原因是确保跨多个数据库连接的事务能够正确地进行协调和管理。
分布式事务涉及多个参与者(例如数据库服务器、应用程序服务器等),每个参与者都可能有自己的事务资源。DTC是一个协调器,负责确保所有参与者在事务的上下文中工作,并协调它们之间的操作。
数据库端需要开启DTC,以便数据库服务器能够参与和管理分布式事务。数据库操作是通过数据库连接进行的,而数据库连接是由数据库驱动程序和底层的DTC进行协调和管理的。因此,数据库端的DTC需要启动并配置正确,以便与应用程序服务器上的DTC进行通信,并执行跨数据库连接的事务操作。
客户端也需要开启DTC,因为应用程序服务器上的DTC需要与数据库端的DTC进行通信,并协调事务的执行。客户端发起的事务操作需要与数据库端的DTC进行交互,以确保所有参与者都遵循事务的一致性、隔离性、持久性和原子性。
通过在数据库端和客户端都开启DTC,可以建立端到端的分布式事务环境,确保所有参与者在事务中的操作得到正确的协调和管理。这样可以保证分布式事务的可靠性和数据的一致性。
总结
DTC内容
DTC(分布式事务协调器)是用于管理分布式事务的组件,它负责协调多个参与者之间的操作,并确保事务的一致性、隔离性、持久性和原子性。下面是关于DTC的一些基本内容:
定义
DTC是Microsoft Windows操作系统的一个组件,用于协调分布式事务。它提供了一个可靠的机制,确保多个参与者在分布式环境中的事务操作能够一致地协调和执行。
功能
DTC提供以下功能:
事务协调:DTC协调多个参与者之间的事务操作,确保它们按照事务的隔离级别和一致性规则执行。
锁管理:DTC管理事务中的锁资源,以保证并发访问的正确性和一致性。
日志记录和恢复:DTC记录事务的操作日志,并在需要时支持事务的回滚和恢复。
分布式事务管理:DTC能够管理涉及多个数据库或资源的分布式事务,确保它们能够以原子方式一起提交或回滚。
事务超时和回滚:DTC监视事务的执行时间,并在超时或错误发生时执行事务的回滚操作。
参与者
在分布式事务中,可能涉及多个参与者,包括数据库服务器、应用程序服务器、消息队列、文件系统等。每个参与者都需要与DTC进行通信,并遵循DTC的协调和管理。
配置和管理
DTC的配置和管理可以通过操作系统的组件服务来完成。通过组件服务管理界面,可以设置DTC的参数、安全性选项、网络访问权限等。正确的配置和管理DTC对于确保分布式事务的可靠性和一致性至关重要。
事务参与方式
在.NET中,可以使用TransactionScope类来实现分布式事务。通过创建TransactionScope对象,可以将多个操作包装在同一个事务中,并使用DTC进行协调和管理。
需要注意的是,使用DTC来管理分布式事务可能涉及到性能、安全性和配置方面的考虑。合理的使用和配置DTC,以及遵循最佳实践,对于确保分布式事务的可靠性和性能至关重要。此外,对于跨多个数据库或资源的分布式事务,还需要确保参与者的支持和兼容性。
TransactionScope
TransactionScope是.NET Framework中用于管理事务范围的类。它提供了简化的方式来执行原子性事务,确保多个操作要么全部成功提交,要么全部回滚。
使用步骤
TransactionScope,需要按照以下步骤进行操作:
- 创建TransactionScope对象,并在代码块的开始处进行初始化。
- 在事务代码块中执行需要参与事务的操作,如数据库操作、文件操作等。
- 如果所有操作都成功执行,并且没有抛出异常,则事务在代码块结束时自动提交。
- 如果任何一个操作失败或抛出异常,则事务被回滚,以保证所有操作的一致性。
展示TransactionScope的使用:
using (TransactionScope scope = new TransactionScope()) { try { // 执行数据库操作 using (SqlConnection connection1 = new SqlConnection(connectionString1)) using (SqlCommand command1 = new SqlCommand(query1, connection1)) { connection1.Open(); command1.ExecuteNonQuery(); } // 执行文件操作 File.WriteAllText(filePath, content); // 提交事务 scope.Complete(); } catch (Exception ex) { // 处理异常 Console.WriteLine("Error: " + ex.Message); } }
注意事项和要点
TransactionScope可以嵌套使用,内部的嵌套事务将自动加入外部事务的范围。
默认情况下,TransactionScope使用可分布式事务协调器(DTC)来管理分布式事务,因此需要确保数据库端和客户端都已开启DTC。
长时间运行的操作或过多的资源使用可能导致事务范围过长,影响性能。
在事务代码块中,应该捕获并处理异常,以便正确处理事务状态。
调用TransactionScope的Complete()方法来标记事务的成功,否则事务将回滚。
总的来说,TransactionScope提供了一种方便且可靠的方式来管理事务的范围,使多个操作能够以原子性的方式执行,确保数据的一致性。使用TransactionScope可以简化事务管理的代码,并提供了异常处理和自动回滚的机制,使开发人员能够更容易地处理复杂的事务操作。