zoukankan      html  css  js  c++  java
  • 我的ORM之五-- 事务

    我的ORM索引

    单库事务与分布式事务

    单库事务: 性能更好,应用于一个数据库时的场景,当数据库发生变化,如拆分为多个服务器,代码需要修改。

    分布式事务:性能相对较差,但有更大的适用场景。当数据库发生变化,如拆分为多个服务器,代码可能不需要修改。

    由于事务会引起资源争抢,互联网平台,越来越趋向无事务处理,追求极致的性能。

    分布式事务

    using (ransactionScope scope = new TransactionScope())
    
         {
    
            //to do something
    
            scope.Complete();
    
         }

    单库事务

    在实际应用中,我更倾向于单库事务。用法也很像分布式事务,可以嵌套。

    string errorMsg = dbr.表1.ExecTransaction(()=>
    
    {
    
      if( 表1操作失败) return "表1失败";
    
      if( 表2操作失败) return "表2失败";
    
      if( 表3操作失败) return "表3失败";
    
     
    
         var msg = 调用其它单库事务方法;
    
      if( msg.HasValue() )  return msg;
    
     
    
         return "";
    
    });

     

    在 ExecTransaction 方法中,返回空值或空字符串,表示成功。 如果返回错误信息,则事务回滚。

    具体实现方法:(需根据项目修改)

    实现思想:在执行事务前,先使用 lock 锁住某个表示该表的对象。使其它使用该表的事务在数据库外排队,防止死锁。

    public static string ExecTransaction(this RuleBase rule, Func<string> func)
    {
        return ExecTransaction(rule, new LockObjectEnum(), func);
    }
    
    /// <summary>
    /// 单库事务安全执行方法
    /// </summary>
    /// <param name="rule"></param>
    /// <param name="func"></param>
    /// <returns></returns>
    public static string ExecTransaction(this RuleBase rule, LockObjectEnum LockObj, Func<string> func)
    {
        var group = rule.GetGroupName().AsString(me.CorpID.ToString());
    
        if (LockObj.HasValue() == false)
        {
            group.MySplit('_').All(g =>
            {
                var e = g.ToEnum<LockObjectEnum>();
                if (e > 0)
                {
                    LockObj = e;
                    return false;
                }
                return true;
            });
        }
    
        var ret = string.Empty;
    
        lock (rule.GetLockObject())
        {
            For2Recusion(LockObj.GetEnumList(), () =>
            {
                ret = _execTransactionWithoutLock(rule, func);
            });
        }
    
        return ret;
    }
    
    private static void For2Recusion(LockObjectEnum[] objs, Action act, int index = 0)
    {
        if (index < objs.Length)
        {
            lock (MyHelper.GetLockObject("ExecTransaction." + objs[index].ToString()))
            {
                For2Recusion(objs, act, index + 1);
            }
        }
        else
        {
            act();
        }
    }
    
    
    private static string _execTransactionWithoutLock(RuleBase rule, Func<string> func)
    {
        var msg = string.Empty;
        if (dbo.CurrentScope != null && dbo.CurrentScope.Transaction != null)
        {
            try
            {
                msg = func();
    
                if (msg.HasValue())
                {
                    return msg;
                }
            }
            catch (Exception e)
            {
                msg = e.Message;
                throw;
            }
            return msg;
        }
        using (var conn = rule.GetDbConnection())
        {
            msg = dbo.Open(conn, () =>
            {
                var tran = conn.BeginTransaction();
                using (var scope = new MyOqlConfigScope(tran))
                {
                    try
                    {
                        msg = func();
    
                        if (msg.HasValue())
                        {
                            tran.Rollback();
                            return msg;
                        }
    
                        tran.Commit();
                    }
                    catch (Exception e)
                    {
                        msg = e.Message;
    
                        if (conn.State != ConnectionState.Closed)
                        {
                            tran.Rollback();
                        }
    
                        throw;
                    }
                    return msg;
                }
            });
        }
        return msg;
    }
  • 相关阅读:
    【解决办法】移动硬盘在电脑上显示“本地磁盘”并且出现打不开的情况
    在Windows上搭建Python环境
    Thymeleaf模板的使用
    thymeleaf中的th:remove用法
    AngularJS PhoneCat代码分析
    AngularJS PhoneCat代码分析
    利用java反射调用类的的私有方法--转
    Java Reflection (JAVA反射) --转载
    Eclipse 常用快捷键 (动画讲解)--转载
    三大JavaScript框架对比——AngularJS、BackboneJS和EmberJS
  • 原文地址:https://www.cnblogs.com/newsea/p/4530530.html
Copyright © 2011-2022 走看看