【问题标题】:MySQL and Transactions not rolling backMySQL 和事务不回滚
【发布时间】:2010-11-10 19:54:34
【问题描述】:

我正在编写一个导入例程,并希望在发生错误时整个导入失败。我正在使用设置为 InnoDB 的 MySQL 数据库和一个 asp 页面来驱动导入。我想启动一个事务,如果发生错误则回滚,如果成功则提交。我的问题是,当第 4 行发生错误时,前 3 个条目保存在数据库中,而不是回滚。

这是我的代码示例:-

        MySqlConnection conn = new MySqlConnection(connStr);
        conn.Open();

        MySqlCommand cmd = new MySqlCommand();

        MySqlTransaction tran = conn.BeginTransaction();

        cmd.Connection = conn;
        cmd.Transaction = tran;

        int ErrorCount = 0;
        do while read from file{
            try{
                if (fail validate){
                    ErrorCount ++;
                    break;
                }
                run store procedure 1 which does insert
                run store procedure 2 which does insert
            }
            catch (exception e){
                ErrorCount ++;
                break;
            }
        }

        if (ErrorCount == 0){
            tran.Commit();
        }
        else{
            tran.RollBack();
        }

        if (conn != null) conn.Close();

我已阅读有关自动提交以及如何在数据库中设置它的信息。唯一的问题是,如果将其设置为关闭,它将如何影响数据库中尚未设置事务的所有其他插入。我也看不到如何从 c# 设置自动提交打开或关闭。

有人知道如何让我的交易回滚吗?

谢谢 谢丽尔

【问题讨论】:

    标签: c# mysql transactions


    【解决方案1】:

    如果您的存储过程中包含隐式提交的事务或语句,则会发生这种情况。

    【讨论】:

      【解决方案2】:

      您只能为您的会话关闭自动提交。尝试执行sql "set autocommit=0"

      【讨论】:

      • 我决定编写自己的导入头表,然后如果失败,我可以删除所有已插入的记录,因为它们现在都有一个 importID。这样,我还可以对导入的内容和频率进行审核。
      • 出于兴趣,我将其添加到我的函数顶部 cmd.CommandText="set autocommit=0"; cmd.CommandType=System.Data.CommandType.Text; cmd.ExecuteNonQuery();它仍然没有回滚。
      【解决方案3】:

      您是否检查过此表的存储引擎?我知道您的数据库默认为 innoDB,但我以前在这种类型的环境中以某种方式创建了 MyISAM 表。

      SHOW CREATE TABLE tablename
      

      【讨论】:

      • 是的,我检查过,它肯定是在 innoDB 设置的。无论如何,谢谢。
      【解决方案4】:

      我相信自动提交是基于每个命令的,所以它不能完全处理你的情况。我认为关键是确保每个存储的 proc 调用都是添加到事务中的新命令。我不倾向于使用 MySQL,但我在 OleDb 上成功使用了以下代码。

      OleDbConnection conn = new OleDB(); //obviously missing important stuff...
      conn.open();
      
      using(OleDbTransaction trans = conn.BeginTransaction()){
          try{
              OleDbCommand cmd1 = new OleDbCommand("insert into t1...", conn, trans);
              cmd1.ExecuteNonQuery();
      
              OleDbCommand cmd2 = new OleDbCommand("insert into t2...", conn, trans);
              cmd2.ExecuteNonQuery();
      
              trans.Commit();
          } catch {
              trans.Rollback();
          }
      }
      
      conn.close();
      

      【讨论】:

        【解决方案5】:

        我遇到了类似的问题。依次失败的存储过程调用了另一个具有START TRANSACTIONCOMMIT 行的存储过程。一旦我删除了这些命令,提交的命令就会按预期工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-12-24
          • 2013-11-22
          • 1970-01-01
          • 1970-01-01
          • 2012-11-12
          • 1970-01-01
          • 2012-09-14
          相关资源
          最近更新 更多