快捷搜索:
来自 计算机编程 2019-12-12 13:12 的文章
当前位置: 67677新澳门手机版 > 计算机编程 > 正文

中跨库事务处明白决方案

  近些日子新接手了生龙活虎项职业,当中有二个主意,须求对作业表张开写入数据,之后记录到日志表中。那有的代码原先是先行者写的,他未有接受任何方案,只是简单的调用Ado.net试行了两回写库操作。由此平时现身系统使用者不断发邮件说多少有难题,经过查阅原因正是在于写库操作中,有有些表写入失利,可是任何表写入成功,招致出现了数量不等同的难题。后来本想改用事务,但意识日志表和业务表不在同贰个数据库下,以致不在同三个IP下,对于那个题目,小编想到了有以下应用方案。

由ado.net管理的作业改为温馨手动提交业务和Commit大概RollBack操作:

step1:依据连接字符串和sql分类,存入Dictionary<string,string>中,Key为连续几日来字符串,Value为针对此数据库的Sql语句,多条用分号隔离;

step2:遍历此Dictionary,张开那一个连接;

step3:对于每种连接,张开工作;

67677新澳门手机版 ,step4:实施针对各种连接的sql,现身谬误则整个rollback,不然全数commit;

step5:关闭连接,记录运行状态,记录日志。

具体代码如下:

  1         //提交事务用的sql
  2         public const string MultiTran = @"BEGIN TRAN
  3                                             {0}";
  4 
  5         /// <summary>
  6         /// 事务返回的信息
  7         /// </summary>
  8         public struct TransInfo
  9         {
 10             /// <summary>
 11             /// sql总条数
 12             /// </summary>
 13             public int Total;
 14             /// <summary>
 15             /// 事务执行是否成功
 16             /// </summary>
 17             public bool IsSuccess;
 18             /// <summary>
 19             /// 失败时的sql
 20             /// </summary>
 21             public string WrongMessage;
 22         }        
 23 
 24         /// <summary>
 25         /// 跨库事务异常对象
 26         /// </summary>
 27         public class TransException : Exception
 28         {
 29             public TransException(string message) : base(message)
 30             {
 31             }
 32 
 33             public string wrongSQL { get; set; }
 34             public string wrongAt { get; set; }
 35             /// <summary>
 36             /// 已经打开的连接
 37             /// </summary>
 38             public List<SqlConnection> DoneConnection = new List<SqlConnection>();
 39             /// <summary>
 40             /// 出现错误的连接
 41             /// </summary>
 42             public SqlConnection CurrentConnection;
 43             /// <summary>
 44             /// 覆盖Exception中的Message字段,使其可写
 45             /// </summary>
 46             public new string Message { get; set; }
 47         }
 48 
 49         /// <summary>
 50         /// 多操作sql,使用事务,用于多库事务
 51         /// <para>
 52         /// 返回值TransInfo字段:IsSuccess 是否成功,
 53         /// Total sql总条数,
 54         /// WrongAt 失败的sql语句
 55         /// </para>
 56         /// </summary>
 57         /// <param name="sqlwithconn">执行的sql和连接字符串列表key:sql,value:连接字符串</param>
 58         /// <param name="connectionString">连接字符串</param>
 59         /// <returns>sadf</returns>
 60         public static TransInfo RunSqlInTrans(Dictionary<string, string> sqlwithconn)
 61         {
 62             var sqltable = new Dictionary<string, string>();
 63             var conntable = new Dictionary<string, SqlConnection>();
 64 
 65             foreach (var i in sqlwithconn)
 66             {
 67                 if (!sqltable.Keys.Contains(i.Value))
 68                 {
 69                     sqltable.Add(i.Value, i.Key); //sqltable的key是连接字符串,value是sql语句
 70                     conntable.Add(i.Value, new SqlConnection(i.Value));    //key是连接字符串,value是连接对象
 71                 }
 72                 else
 73                 {
 74                     sqltable[i.Value]  = ";"   i.Key;
 75                 }
 76             }
 77 
 78             try
 79             {
 80                 var wrongEx = new TransException("");
 81                 foreach (var i in sqltable)
 82                 {
 83                     //遵照晚开早关原则,在此处打开数据库连接
 84                     conntable[i.Key].Open();
 85                     //连接打开后,将连接对象放入异常处理对象中做记录
 86                     wrongEx.DoneConnection.Add(conntable[i.Key]);
 87                     var dc = new SqlCommand(string.Format(MultiTran, i.Value), conntable[i.Key]);
 88                     try
 89                     {
 90                         dc.ExecuteNonQuery();
 91                     }
 92                     catch (Exception ex)
 93                     {
 94                         //出现异常,抛出异常处理对象
 95                         wrongEx.CurrentConnection = conntable[i.Key];
 96                         wrongEx.wrongAt = i.Key;
 97                         wrongEx.wrongSQL = sqltable[i.Key];
 98                         wrongEx.Message = ex.Message;
 99                         throw wrongEx;
100                     }
101                 }
102                 //全部执行完毕没有发现错误,提交事务
103                 foreach (var i in conntable)
104                 {
105                     var dc = new SqlCommand("COMMIT TRAN", i.Value);
106                     dc.ExecuteNonQuery();
107                     i.Value.Close();
108                 }
109                 return new TransInfo()
110                 {
111                     IsSuccess = true,
112                     Total = sqlwithconn.Count,
113                     WrongMessage = ""
114                 };
115 
116             }
117             catch (TransException e)   //1.回滚所有操作2.关闭所有已经打开的数据库连接4.生成错误对象
118             {
119                 foreach (var i in e.DoneConnection)
120                 {
121                     if (!i.Equals(e.CurrentConnection))
122                     {
123                         var dc = new SqlCommand("ROLLBACK TRAN", i);
124                         dc.ExecuteNonQuery();
125                     }
126                     i.Close();
127                 }
128                 return new TransInfo()
129                 {
130                     IsSuccess = false,
131                     Total = sqlwithconn.Count,
132                     WrongMessage = string.Format("在连接{0}中,操作{1}出现错误,错误信息:{2}", e.wrongAt, e.wrongSQL, e.Message)
133                 };
134             }
135         }

 那样消除了跨库数据表处理有的时候因为网络难点或别的一时性难点引致的数目不附近的标题。不过那个施工方案最大的问题不怕在于品质难点上,比方尽管有两个库要是为A,B,C,D,在那之中C库的多少改良写入比较复杂,那么在A,B库开启事务后,必需等待C和D库完结或失利后,事务才足以了结,连接才能放出,那时,A库和B库正是处在挂起状态,假使处在高IO的临蓐条件中的话,这几个天性的损失只怕是致命的,所以那几个方案一定要用来简单的sql管理,而且管理sql无法太多也许太复杂。并且现身互联网波动的话,损失会越来越大。幸运的是本身所接手的这么些事情,是在内网蒙受中,同一时候只用两句sql在多个库中,所以用那么些方案难题十分小。

小结:针对这几个主题材料,我以为当初安插数据库时,能幸免跨库就决然要制止。

黄金年代旦我们有何更好的缓慢解决方案以来,希望和贵胄多多沟通和指教。

 

本文由67677新澳门手机版发布于计算机编程,转载请注明出处:中跨库事务处明白决方案

关键词: