2010-11-10 2 views
3

Я пишу процедуру импорта и хочу, чтобы весь импорт был сбой при возникновении ошибки. Я использую базу данных MySQL, которая настроена на InnoDB и страницу 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(); 

Я прочитал о AUTOCOMMIT и как вы должны установить его в базу данных. Единственная проблема заключается в том, что если он отключит его, как он повлияет на все другие вставки в базу данных, у которых еще нет установленных транзакций. Также я не вижу, как включить или отключить автокоманду с C#.

Кто-нибудь знает, как вернуть мои транзакции?

Благодаря Шерил

ответ

0

Вы можете отключить AutoCommit для вас только сессии. Попробуйте выполнить sql «set autocommit = 0»

+0

Я решил написать свою собственную таблицу заголовков импорта, а затем, если она не удалась, я смогу удалить все записи, которые были вставлены, поскольку все они будут иметь importID. Таким образом, у меня также есть контрольный журнал о том, что импортируется и как часто. – Cheryl

+0

Просто из интереса я добавил это в начало своей функции cmd.CommandText = "set autocommit = 0"; cmd.CommandType = System.Data.CommandType.Text; cmd.ExecuteNonQuery(); и он все еще не откат. – Cheryl

0

Вы проверили механизм хранения для этой таблицы? Я знаю, что ваш db по умолчанию имеет значение innoDB, но я каким-то образом создал таблицы MyISAM в этом типе среды раньше.

SHOW CREATE TABLE tablename 
+0

Да, я проверил, и он определенно установлен в innoDB. В любом случае спасибо. – Cheryl

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 TRANSACTION и COMMIT. Как только я удалил эти команды, команда совершила работу как ожидалось.

Смежные вопросы