2010-11-10 115 views
3

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

这里是我的代码示例: -

 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#。

任何人都知道如何让我的交易回滚?

感谢 谢丽尔

回答

0

您可以关闭自动提交的只有你的会话。尝试执行sql“set autocommit = 0”

+0

我已经决定编写自己的导入头表,然后如果失败,我可以删除所有已经插入的记录,因为它们现在都会有一个importID。通过这种方式,我还有一个关于正在导入的内容和频率的审计跟踪。 – Cheryl 2010-11-10 20:44:36

+0

出于兴趣,我将此添加到我的功能顶部 cmd.CommandText =“set autocommit = 0”; cmd.CommandType = System.Data.CommandType.Text; cmd.ExecuteNonQuery(); 它仍然没有回滚。 – Cheryl 2010-11-10 20:50:57

0

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

SHOW CREATE TABLE tablename 
+0

是的,我检查了它,它肯定是在innoDB上设置的。不管怎么说,多谢拉。 – Cheryl 2010-11-10 20:41:54

0

我相信Autocommit是在每个命令的基础上,所以它不会很好地处理您的情况。我认为关键是确保每个存储的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(); 
1

如果你的存储过程有事务或者有隐式提交的语句,那么会发生这种情况。

0

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