• 如何实现SQL事务的提交,又不对外进行污染(2)


    紧接着上文,这里主要记录事务操作,实现多实体的功能

    在SqlTran类中添加方法如下:

    1、两个不同实体类型的事务方法:

     1         /// <summary>
     2         /// 执行事务(事务中不同实体)
     3         /// </summary>
     4         /// <typeparam name="T">实体</typeparam>
     5         /// <param name="method">要执行的方法(SqlTransaction 默认传入为null)</param>
     6         /// <param name="obj1">参数值</param>
     7         /// <returns></returns>
     8         public static Int32 ExecuteTran<M, N>(Func<M, SqlTransaction, Int32> method1, Func<N, SqlTransaction, Int32> method2, M obj1, N obj2)
     9             where M : new()
    10             where N : new()
    11         {
    12             Int32 count = 0;
    13             SqlConnection conn = null;
    14             SqlTransaction tran = null;
    15             try
    16             {
    17                 conn = new SqlConnection(Repository.connStr);
    18                 conn.Open();
    19                 tran = conn.BeginTransaction();
    20 
    21                 count += method1(obj1, tran);
    22                 count += method2(obj2, tran);
    23 
    24                 tran.Commit();
    25                 return count;
    26             }
    27             catch (Exception ex)
    28             {
    29                 tran.Rollback();
    30                 return -1;
    31             }
    32             finally
    33             {
    34                 if (tran != null)
    35                     tran.Dispose();
    36                 if (conn != null)
    37                 {
    38                     conn.Close();
    39                     conn.Dispose();
    40                 }
    41             }
    42 
    43         }
    44 
    45         /// <summary>
    46         /// 执行事务(事务中不同实体)
    47         /// </summary>
    48         /// <typeparam name="T">实体</typeparam>
    49         /// <param name="method">要执行的方法(SqlTransaction 默认传入为null)</param>
    50         /// <param name="obj1">参数值</param>
    51         /// <returns></returns>
    52         public static Int32 ExecuteTran<M, N>(IList<Func<M, SqlTransaction, Int32>> methods1, IList<Func<N, SqlTransaction, Int32>> methods2, IList<M> objs1, List<N> objs2)
    53             where M : new()
    54             where N : new()
    55         {
    56             Int32 count = 0;
    57             SqlConnection conn = null;
    58             SqlTransaction tran = null;
    59             try
    60             {
    61                 conn = new SqlConnection(Repository.connStr);
    62                 conn.Open();
    63                 tran = conn.BeginTransaction();
    64 
    65                 if (methods1.Count() != objs1.Count())
    66                     return -1;
    67                 if (methods2.Count() != objs2.Count())
    68                     return -1;
    69 
    70                 for (int i = 0; i < objs1.Count(); i++)
    71                     count += methods1[i](objs1[i], tran);
    72                 for (int i = 0; i < objs2.Count(); i++)
    73                     count += methods2[i](objs2[i], tran);
    74 
    75                 tran.Commit();
    76                 return count;
    77             }
    78             catch (Exception ex)
    79             {
    80                 tran.Rollback();
    81                 return -1;
    82             }
    83             finally
    84             {
    85                 if (tran != null)
    86                     tran.Dispose();
    87                 if (conn != null)
    88                 {
    89                     conn.Close();
    90                     conn.Dispose();
    91                 }
    92             }
    93 
    94         }
    View Code

        参数为List的时候,注意对应关系

        methods1-->objs1

        methods2-->objs2

    2、测试方法:

     1         public void Test()
     2         {
     3             Repository repository = new Repository();
     4             
     5             Orders order11 = new Orders() { Id = 11, Name = "name11" };
     6             Orders order21 = new Orders() { Id = 12, Name = "name12" };
     7             Orders order31 = new Orders() { Id = 13, Name = "name13" };
     8             OrderDetail orderDetail11 = new OrderDetail() { Id = 11, OrderId = 1, Name = "namedetail11" };
     9             OrderDetail orderDetail12 = new OrderDetail() { Id = 12, OrderId = 1, Name = "namedetail12" };
    10 
    11             var count1 = SqlTran.ExecuteTran<Orders, OrderDetail>(repository.AddOrder, repository.AddOrderDetail, order11, orderDetail11); //不同方法,不同实体类型
    12 
    13             List<Func<Orders, SqlTransaction, Int32>> listFuncOrders = new List<Func<Orders, SqlTransaction, Int32>>();
    14             List<Func<OrderDetail, SqlTransaction, Int32>> listFuncOrdersDetail = new List<Func<OrderDetail, SqlTransaction, Int32>>();
    15             List<Orders> listOrder = new List<Orders>();
    16             List<OrderDetail> listOrderDatail = new List<OrderDetail>();
    17 
    18             listFuncOrders.Add(repository.AddOrder);
    19             listFuncOrders.Add(repository.AddOrder);
    20             listOrder.Add(order21);
    21             listOrder.Add(order31);
    22 
    23             listFuncOrdersDetail.Add(repository.AddOrderDetail);
    24             listFuncOrdersDetail.Add(repository.UpdateOrderDetail);
    25             listOrderDatail.Add(orderDetail12);
    26             orderDetail11.Name = "namedetail11Update";
    27             listOrderDatail.Add(orderDetail11);
    28 
    29             var count2 = SqlTran.ExecuteTran<Orders, OrderDetail>(listFuncOrders, listFuncOrdersDetail, listOrder, listOrderDatail);
    30         }
    View Code

    3、三个不同实体类型的事务方法:定义

    public static Int32 ExecuteTran<M, N, T>(Func<M, SqlTransaction, Int32> method1, Func<N, SqlTransaction, Int32> method2, Func<T, SqlTransaction, Int32> method3, M obj1, N obj2, T obj3)
    where M : new()
    where N : new()
    where T : new()

      所以根据实体的个数进行定义就ok,之后就可以重用了

    缺点之一:每个事务方法中大部分的代码是一样的,只有委托执行方法部分有微小的变化(如:count += method(obj1, tran); ),本人目前没有更好的办法把这块相同的代码提取出来进行共用,希望看到这里的同行,如果有好的解决方案,希望能拿出来互相交流!指点迷津。

  • 相关阅读:
    a 超链接标签
    select(下拉标签和textarea(文本框)
    input标签
    input 标签
    div 标签
    body 标签
    STL__网上资料
    STL_iterator返回值
    STL_算法_中使用的函数对象
    STL_std::iterator
  • 原文地址:https://www.cnblogs.com/liujinwu-11/p/4206311.html
Copyright © 2020-2023  润新知