Почему SQL Транзакция не откатывается после потери соединения - C#? - PullRequest
0 голосов
/ 21 марта 2020

Я использую MariaDB 10.3.21 и мне интересно, почему откат не выполняется с сервера SQL после потери соединения.

Я обновляю несколько таблиц с кодом ниже. Чтобы проверить, выполняется ли откат со стороны сервера после потери соединения, я установил точку останова для команды objTransaction.Commit () и, нажав ее, прервал сетевое соединение.

К сожалению, обновление поля захватываются без команды фиксации. Я предположил, что если соединение потеряно, сервер выполнит неявный откат.

Есть идеи? Большое спасибо!

    public void ExecuteSQL(List<string> pQueryList)
    {
        using (MySqlConnection objConnection = new MySqlConnection(ConnectionString))
        {
            try
            {
                objConnection.Open();

                MySqlCommand objCommand = objConnection.CreateCommand();
                MySqlTransaction objTransaction;

                // Start Transaction
                objTransaction = objConnection.BeginTransaction();

                // Must assign both transaction object and connection
                // to Command object for a pending local transaction
                objCommand.Connection = objConnection;
                objCommand.Transaction = objTransaction;

                try
                {
                    // Set autocommit = off the this session
                    //objCommand.CommandText = "SET autocommit = 0";
                    objCommand.ExecuteNonQuery();

                    foreach (string query in pQueryList)
                    {
                        // Execute the SQL Queries
                        objCommand.CommandText = query;

                        if (objCommand.ExecuteNonQuery() <= 0)
                        {
                            throw (new Exception("Fehler bei ExecuteNonQuery. Anzahl der betroffenen Zeilen fehlerhaft."));
                        }
                    }

                    // Commit Transaction
                    objTransaction.Commit();
                }
                catch (Exception)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        // Rollback 3x versuchen (falls Netzwerkverbindung abgebrochen ist)
                        try
                        {
                            objTransaction.Rollback();
                            break;
                        }
                        catch (Exception)
                        {
                            Thread.Sleep(100);
                        }
                    }                        
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Das speichern in die Datenbank ist fehlgeschlagen!\n\n" + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
    }

1 Ответ

0 голосов
/ 21 марта 2020

Я думаю, что вам нужно отключить функцию «автокоммит», она включена по умолчанию.

Что такое автокоммит?

Параметр, который вызывает операцию фиксации после каждого SQL заявление. Этот режим не рекомендуется для работы с таблицами InnoDB с транзакциями, которые охватывают несколько операторов. Это может повысить производительность транзакций только для чтения в таблицах InnoDB, где минимизирует накладные расходы, связанные с блокировкой и генерацией данных отмены, особенно в MySQL 5.6.4 и выше. Это также подходит для работы с таблицами MyISAM, где транзакции не применяются.

(цитата взята из https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_autocommit)

Подробнее об автоматической фиксации и ее отключении читайте здесь: https://dev.mysql.com/doc/refman/5.6/en/commit.html

...