我正在编写一个导入例程,如果发生错误,则希望整个导入失败。我正在使用设置为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();
我已阅读过有关autocommit以及如何在数据库中设置它的信息。唯一的问题是,如果它将其设置为关闭它将如何影响数据库中尚未设置事务的所有其他插入。此外,我无法看到如何从c#开启或关闭自动提交。
任何人都知道如何让我的交易回滚?
由于 谢丽尔
答案 0 :(得分:1)
如果您的存储过程中包含带有隐式提交的事务或语句,则会发生这种情况。
答案 1 :(得分:0)
您可以仅为会话关闭自动提交。尝试执行sql“set autocommit = 0”
答案 2 :(得分:0)
您是否检查了此表的存储引擎?我知道你的db默认为innoDB,但我之前以某种方式在这种类型的环境中创建了MyISAM表。
SHOW CREATE TABLE tablename
答案 3 :(得分:0)
我认为Autocommit是基于per命令的,所以它不会完全处理你的情况。我认为关键是要确保每个存储的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();
答案 4 :(得分:0)
我有类似的问题。反过来失败的存储过程调用了另一个具有START TRANSACTION
和COMMIT
行的存储过程。一旦我删除了这些命令,就会按预期工作。