繁体   English   中英

如何启动数据库事务,在MySQL上运行多个查询,然后使用C#提交或回滚?

[英]How to start DB transaction, run multiple queries on MySQL then commit or rollback using c#?

我有一个通用类,该类允许我在MySQL数据库上运行查询。

我在此类中看到的唯一问题是,它会打开连接并运行查询并关闭连接。

现在,我需要能够

  1. START TRANSACTION;
  2. SELECT ...
  3. INSERT INTO table1...
  4. INSERT INTO table2...
  5. INSERT INTO table3...
  6. 如果以上所有查询均正常运行,则COMMIT;错误COMMIT; 否则ROLLBACK;

是的,我需要一个事务,并且我需要确保所有查询都可以100%运行,或者需要回滚并更正错误,然后再次进行皮重加载。

如何修改我的课程以允许我执行上述步骤?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using MySql.Data.MySqlClient;
using System.Windows.Forms;


namespace RM
{
    public class dbConnetion
    {
        //private OdbcConnection conn; 
        private static readonly string mServer = "localhost";
        private static readonly string mDatabase = "my_db_name";
        private static readonly string mUid = "my_db_user";
        private static readonly string mPassword = "my_user_password";
        private static readonly string mPort = "3306";
        private string conn_string = String.Format("server={0};user={1};database={2};port={3};password={4};", mServer, mUid, mDatabase, mPort, mPassword);


        public string SYSTEM_NAME { get; set; }

        public dbConnetion()
        {
            Initilize_System_Settings();
        }

        // query the data base
        public IEnumerable<T> getData<T>(string query, List<MySqlParameter> pars, Func<IDataRecord, T> transform)
        {
            using (var conn = new MySqlConnection(conn_string))
            using (var cmd = new MySqlCommand(query, conn))
            {
                if (pars != null)
                {
                    foreach (MySqlParameter p in pars)
                    {
                        cmd.Parameters.Add(p);
                    }
                }

                conn.Open();

                using (var rdr = cmd.ExecuteReader())
                {

                    while (rdr.Read())
                    {
                        yield return transform(rdr);
                    }
                }

                conn.Close();
            }
        }

        // query the data base
        public T getValue<T>(string query, List<MySqlParameter> pars)
        {
            T value;
            using (var conn = new MySqlConnection(conn_string))
            using (var cmd = new MySqlCommand(query, conn))
            {

                if (pars != null)
                {
                    foreach (MySqlParameter p in pars)
                    {
                        cmd.Parameters.Add(p);
                    }
                }


                try
                {
                    conn.Open();
                    object rawValue = cmd.ExecuteScalar();

                    if (rawValue != null)
                    {
                        value = (T)Convert.ChangeType(rawValue, typeof(T));
                    }
                    else
                    {
                        value = default(T);
                    }

                }
                catch (Exception ex)
                {

                    Common.Alert(ex.ToString(), "SQL Error");
                    value = default(T);

                }
                finally
                {
                    conn.Close();
                }

            }

            return value;
        }

        public bool processQuery(string strSQL, List<MySqlParameter> pars)
        {
            bool toReturn = true;
            using (var conn = new MySqlConnection(this.conn_string))
            using (var cmd = new MySqlCommand(strSQL, conn))
            {

                foreach (MySqlParameter param in pars)
                {
                    cmd.Parameters.Add(param);
                }

                try
                {
                    conn.Open();
                    cmd.ExecuteNonQuery();
                }
                catch (MySqlException ex)
                {
                    Common.Alert(ex.ToString(), "SQL Error");
                    toReturn = false;
                }
                finally
                {
                    conn.Close();
                }
            }

            return toReturn;
        }
    }
}

我的第一个想法是在getData方法中添加一个新参数,以允许我在存在打开事务的情况下无法打开/关闭连接,例如

// query the data base
        public IEnumerable<T> getData<T>(string query, List<MySqlParameter> pars, Func<IDataRecord, T> transform, bool inTransaction = false)
        {
            using (var conn = new MySqlConnection(conn_string))
            using (var cmd = new MySqlCommand(query, conn))
            {
                if (pars != null)
                {
                    foreach (MySqlParameter p in pars)
                    {
                        cmd.Parameters.Add(p);
                    }
                }
                if(! inTransaction){
                    conn.Open();
                }
                using (var rdr = cmd.ExecuteReader())
                {

                    while (rdr.Read())
                    {
                        yield return transform(rdr);
                    }
                }
                if(! inTransaction){
                    conn.Close();
                }
            }
        }

但我认为这是行不通的,因为using语句

trans = Conn.BeginTransaction();
trans.Commit();
trans.Rollback();

无法访问SqlTransaction对象以在catch块中回滚

然后,您必须确定在哪里开始和结束交易,

using (var conn = new MySqlConnection(conn_string))
{
    var tx = conn.BeginTransaction();
    try
    {
        using (var cmd1 = new MySqlCommand(query1, conn))
        {
           cmd1.Transaction = tx;
           //do cmd 1 stuff here
        }

        using (var cmd2 = new MySqlCommand(query2, conn))
        {
           cmd2.Transaction = tx;
           //do cmd 1 stuff here
        }

       //do other commands....

       tx.Commit(); //or Rollback() based on results
    }
    catch (Exception ex)
    {
       tx.Rollback();
       throw ex;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM