分布式事务(转)

原文地址:http://blog.csdn.net/jiben2qingshan/article/details/23547887

概述

       SqlTransaction可以解决同一个数据库的事务控制,但是,不能解决不同数据库的事务控制,今天就说一说,这个的解决方法,即:TransactionScope的应用。

        本篇博客的的思路就是先进行一些相应的配置(开启DTC服务,配置MSDTC,配置防火墙,配置数据库管理系统),然后再进行一个实例的展示(代码),最后进行简单原理的介绍和总结。

        了解了本篇博客的流程和结构后,接下来就看相应具体的内容吧!


开启DTC服务

    方式一

        计算机—管理—服务—Distributed(分布式)Link Tracking Client—属性—开启

    方式二

        字符命令子界面输入:net start msdtc


设置MSDTC

   命令界面输入:dcomcnfg.exe(或者:控制面板—管理工具—组件服务)



防火墙设置

       有两种方法:1、直接关闭防火墙(不建议使用,以前数据库连接的时候这样干过);2、进行如下图的设置



数据库管理系统设置

       因为要实现多个数据库系统之间事务的控制,所以,数据库系统也需要做相应的设置,具体如下图。



代码

       下面是一个简单的Demo,实现了两个功能:1、同一数据库系统,不同数据库的事务控制;2、不同数据库系统的事务控制。

       控制台代码

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using System.Transactions;  
  7.   
  8. namespace 事务.分布式  
  9. {  
  10.     class Program  
  11.     {  
  12.         static void Main(string[] args)  
  13.         {  
  14.             #region 同一个数据库服务器,操作不同的数据库  
  15.             //using (TransactionScope tran = new TransactionScope())  
  16.             //{  
  17.             //    OperateDataBase operateDataBase = new OperateDataBase();  
  18.             //    int i = operateDataBase.Execute1();  
  19.             //    int j = operateDataBase.Execute2();  
  20.             //    tran.Complete();  
  21.             //}    
  22.             #endregion  
  23.  
  24.             #region 不同的数据库服务器  
  25.             using (TransactionScope tran = new TransactionScope())  
  26.             {                  
  27.   
  28.                 OperateDifferentDataBaseServer operateDifferentDataBaseServer = new OperateDifferentDataBaseServer();  
  29.                 int i = operateDifferentDataBaseServer.Execute1();  
  30.                 int j = operateDifferentDataBaseServer.Execute2();  
  31.                 tran.Complete();     
  32.             }  
  33.             #endregion  
  34.         }  
  35.     }  
  36. }  

       OperateDataBase.cs类(同一数据库服务器,不同数据库)

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using System.Data;  
  7. using System.Data.SqlClient;  
  8. using System.Configuration;  
  9.   
  10. namespace 事务.分布式  
  11. {  
  12.     public class OperateDataBase  
  13.     {  
  14.         private SqlConnection sqlCon1;  
  15.         private SqlConnection sqlCon2;  
  16.         private SqlCommand sqlCom;  
  17.  
  18.         #region 数据库系统1—数据库1—连接对象  
  19.         private void GetConnection1() {  
  20.             if (sqlCon1 == null)  
  21.             {  
  22.                 sqlCon1 = new SqlConnection(ConfigurationManager.ConnectionStrings["strCon1"].ToString());  
  23.             }  
  24.             if (sqlCon1.State == ConnectionState.Closed)  
  25.             {  
  26.                 sqlCon1.Open();  
  27.             }  
  28.         }  
  29.         #endregion  
  30.  
  31.         #region 数据库系统1—数据库2—连接对象  
  32.         private void GetConnection2() {  
  33.             if (sqlCon2 == null)  
  34.             {  
  35.                 sqlCon2 = new SqlConnection(ConfigurationManager.ConnectionStrings["strCon2"].ToString());  
  36.             }  
  37.             if (sqlCon2.State == ConnectionState.Closed)  
  38.             {  
  39.                 sqlCon2.Open();  
  40.             }  
  41.         }  
  42.         #endregion  
  43.  
  44.         #region 数据库系统1—数据库1—添加数据  
  45.         public int Execute1() {  
  46.             GetConnection1();  
  47.             sqlCom = new SqlCommand("insert into DataTable2(id,name) values(1,'张三')");  
  48.             sqlCom.Connection = sqlCon1;  
  49.             return sqlCom.ExecuteNonQuery();  
  50.         }  
  51.         #endregion  
  52.  
  53.         #region 数据库系统1—数据库2—添加数据  
  54.         public int Execute2() {  
  55.             GetConnection2();  
  56.             sqlCom = new SqlCommand("insert into DataTable2(id,name) values(1,'李四')");  
  57.             sqlCom.Connection = sqlCon2;  
  58.             return sqlCom.ExecuteNonQuery();  
  59.         }  
  60.         #endregion  
  61.     }  
  62. }  

       OperateDifferentDataBaseServer.cs(不同数据库系统)

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using System.Data;  
  7. using System.Data.SqlClient;  
  8. using System.Configuration;  
  9.   
  10. namespace 事务.分布式  
  11. {  
  12.     public class OperateDifferentDataBaseServer  
  13.     {  
  14.         private SqlConnection sqlCon1;  
  15.         private SqlConnection sqlCon2;  
  16.         private SqlCommand sqlCom;  
  17.  
  18.         #region 数据库服务器系统1—数据库连接对象  
  19.         private void GetConnection1()  
  20.         {  
  21.             if (sqlCon1 == null)  
  22.             {  
  23.                 sqlCon1 = new SqlConnection(ConfigurationManager.ConnectionStrings["strConS1"].ToString());  
  24.             }  
  25.             if (sqlCon1.State == ConnectionState.Closed)  
  26.             {  
  27.                 sqlCon1.Open();  
  28.             }  
  29.         }  
  30.         #endregion  
  31.          
  32.         #region 数据库服务器系统2—数据库连接对象  
  33.         private void GetConnection2()  
  34.         {  
  35.             if (sqlCon2 == null)  
  36.             {  
  37.                 sqlCon2 = new SqlConnection(ConfigurationManager.ConnectionStrings["strConS2"].ToString());  
  38.             }  
  39.             if (sqlCon2.State == ConnectionState.Closed)  
  40.             {  
  41.                 sqlCon2.Open();  
  42.             }  
  43.         }  
  44.         #endregion  
  45.  
  46.         #region 数据服务器系统1—添加数据  
  47.         public int Execute1()  
  48.         {  
  49.             GetConnection1();  
  50.             sqlCom = new SqlCommand("insert into DataTable2(id,name) values(17,'张三')");  
  51.             sqlCom.Connection = sqlCon1;  
  52.             return sqlCom.ExecuteNonQuery();  
  53.         }  
  54.         #endregion  
  55.  
  56.         #region 数据库管理系统2—添加数据  
  57.          public int Execute2()  
  58.         {  
  59.             GetConnection2();  
  60.             sqlCom = new SqlCommand("insert into DataTable2(id,name) values(17,'李四')");  
  61.             sqlCom.Connection = sqlCon2;  
  62.             return sqlCom.ExecuteNonQuery();  
  63.         }  
  64.         #endregion  
  65.     }  
  66. }  

       配置文件的代码和数据库代码,可以通过阅读上面的代码,自己写出来,这里就不提供了


简单原理的介绍

       我们系统在多台计算机上,那么,到底哪些机子需要进行上面的配置呢?这里大致说一下它的原理。

       要想实现A机上运行代码,并且通过代码实现事务控制B机和C机上的数据库系统,那么,最基本的一点,A机要能和B机和C机进行一些特殊的交流,这个交流 的实现就依赖于相应的服务,即我们要开启相应的服务,这个服务不是简单的开启,需要我们进行一些设置,开启服务后,我们还要告诉防火墙,你给我放行这个口 或这个程序,这些完成后,我们再需要做的就是进行数据库系统的设置,最后做的就是相应的编程了。


总结

       这个demo的实现大概用了一整天的时间,其间谢谢欢哥和磊磊的帮助。

       下图是关于TransactionScope的总结图

posted @ 2015-09-24 13:22  杨杨得意  阅读(104)  评论(0编辑  收藏  举报