【问题标题】:Ways to implement Nested Transactions in Nested Methods在嵌套方法中实现嵌套事务的方法
【发布时间】:2017-01-19 04:34:31
【问题描述】:

假设我有一个像下面这样的类,我怎样才能实现使 MasterMethod (MethodA, MethodB, and MethodC) 中的所有调用方法继承从 MasterMethod 实例化的 MySqlTransaction 对象?

private MySqlConnection OpenConnection() {
    try {
        MySqlConnection DbConn = new MySqlConnection("~connectionstring");
        DbConn.Open();

        return DbConn;
    } catch(Exception Ex) {
        throw Ex;
    }
}

public void MasterMethod() {
    using(MySqlConnection DbConn = OpenConnection()) {
        using(MySqlTransaction DbTrans = DbConn.BeginTransaction()) {
            try {
                MethodA();
                MethodB(Param1);
                MethodC(Param1, Param2);

                DbTrans.Commit();
            } catch(Exception Ex) {
                DbTrans.Rollback();
                throw Ex;
            }
        }
    }
}

public void MethodA() {
    using(MySqlConnection DbConn = OpenConnection()) {
        using(MySqlTransaction DbTrans = DbConn.BeginTransaction()) {
            try {
                // Lots and Lots of things to do

                DbTrans.Commit();
            } catch(Exception Ex) {
                DbTrans.Rollback();
                throw Ex;
            }
        }
    }
}

public void MethodB(int Param1) {
    using(MySqlConnection DbConn = OpenConnection()) {
        using(MySqlTransaction DbTrans = DbConn.BeginTransaction()) {
            try {
                // Lots and Lots of things to do

                DbTrans.Commit();
            } catch(Exception Ex) {
                DbTrans.Rollback();
                throw Ex;
            }
        }
    }
}

public void MethodC(string Param1, string Param2) {
    using(MySqlConnection DbConn = OpenConnection()) {
        using(MySqlTransaction DbTrans = DbConn.BeginTransaction()) {
            try {
                // Lots and Lots of things to do

                DbTrans.Commit();
            } catch(Exception Ex) {
                DbTrans.Rollback();
                throw Ex;
            }
        }
    }
}

在我当前的架构中,查询会在特定 Method 的块到达其末尾后立即提交,而不是等待 MasterMethod 的 try 块最底部的 DbTrans.Commit()

我怎样才能使它 (the MySqlTransaction Object) 的行为方式必须等待所有 3 个嵌套/调用方法 (MethodA, MethodB, MethodC) 才能提交(或回滚)对数据库的更改?

【问题讨论】:

    标签: c# mysql methods transactions nested


    【解决方案1】:

    希望以下代码对您有所帮助:

    您必须使用 2 个不同的连接对象来维护状态(根据您的要求)。我已经发布了一个通用的数据库连接代码,您可以按照自己的方式使用它。

    public class ConnectionClass
    {
        public string ConnectionString = ConfigurationManager.ConnectionStrings["xyz"].ConnectionString;
        public SqlConnection conTrans = new SqlConnection();
        public SqlTransaction dbTrans;
        public SqlConnection sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["xyz"].ConnectionString);
        public SqlTransaction sqlTrans;
    
    
    
        public bool BeginConTrans()
        {
            try
            {
                conTrans.ConnectionString = ConnectionString;
                conTrans.Open();
                dbTrans = conTrans.BeginTransaction();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    
    
        public bool CommitConTrans()
        {
            try
            {
                dbTrans.Commit();
                conTrans.Close();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    
    
        public bool RollbackConTrans()
        {
            try
            {
                dbTrans.Rollback();
                conTrans.Close();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    
    
        public bool ExecuteNonQueryTrans(string proc, SqlParameter[] par)
        {
            SqlCommand cmd = new SqlCommand();
            try
            {
                if (par != null)
                {
    
                    for (int i = 0; i <= par.Length - 1; i++)
                    {
                        cmd.Parameters.Add(par[i]);
                    }
                }
                cmd.Connection = conTrans;
                cmd.Transaction = dbTrans;
                cmd.CommandText = proc;
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.ExecuteNonQuery();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
    

    EDIT - 如何在你的逻辑中使用它

    public void MasterMethod()
        {
            try
            {
                BeginConTrans();
                // your methods A,B,C
                //must use ExecuteNonQueryTrans for your get/put data
    
            }
            catch (Exception ex)
            {
                //if any method fails handle exception and rollback the transcation
                RollbackConTrans();
            }
            CommitConTrans(); // if success ,commit the transcation
    
        }
    

    【讨论】:

    • 我不知道是不是只有我,或者你的代码有点……你知道……乱七八糟。我认为这是我的错,我忘记了我正在使用 Dapper ORM 框架
    • @TheQuestioner 现在检查我的答案。是的,因为有些空格,格式不好:)
    • 这可能会派上用场。我会保留这个作为参考。问题是我在 MySQL 服务器下运行并使用 Dapper ORM :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多