Как выполнить вставки и обновления вне транзакции в T-SQL - PullRequest
6 голосов
/ 27 января 2009

У меня есть хранимые процедуры в SQL Server T-SQL, которые вызываются из .NET в рамках транзакции.

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

Я обнаружил, что если несколько человек попробуют одну и ту же вещь одновременно, 1 или 2 из них станут жертвами тупиковых ситуаций транзакций. В настоящий момент я предполагаю, что происходит какая-то блокировка при вставке в таблицы аудита.

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

Может кто-нибудь помочь мне сделать это в T-SQL?

Спасибо, Рич

Обновление. С тех пор я обнаружил, что аудит не связан с тупиком транзакции, благодаря предложению Джоша использовать SQL Profiler для отслеживания источника тупика.

Ответы [ 4 ]

5 голосов
/ 27 января 2009

TranactionScope поддерживает подавление:

using (TransactionScope scope = new TransactionScope())
{

    // Transactional code...


    // Call a SQL stored procedure (but suppress the transaction)
    using (TransactionScope suppress = new TransactionScope(TransactionScopeOption.Suppress))
    {
        using (SqlConnection conn = new SqlConnection(...))
        {
            conn.Open();
            SqlCommand sqlCommand = conn.CreateCommand();
            sqlCommand.CommandType = CommandType.StoredProcedure;
            sqlCommand.CommandText = "MyStoredProcedure";
            int rows = (int)sqlCommand.ExecuteScalar();
        }
    }

    scope.Complete();

}

Но мне пришлось бы задать вопрос, почему ведение журнала / аудит будут выполняться вне транзакции? Если транзакция откатывается, вы все равно сохраняете записи аудита / регистрации, и это, вероятно, не то, что вам нужно.

Вы не предоставили много информации о том, как вы регистрируетесь. Есть ли в вашей таблице аудита внешние ключи, указывающие на ваши основные активные таблицы? Если это так, удалите внешние ключи (при условии, что записи аудита поступают только из «известных» приложений).

2 голосов
/ 27 января 2009

вы можете сохранить ваши аудиты в табличной переменной (на которые не влияют транзакции), а затем в конце вашего SP (вне области транзакции) вставить строки в таблицу аудита.

Однако, похоже, что вы пытаетесь устранить симптомы, а не проблему. Вы можете отследить взаимоблокировки и исправить их.

1 голос
/ 27 января 2009

Почему вы обновляете таблицу аудита? Если бы вы только делали вставки, вы могли бы помочь предотвратить эскалацию блокировки. Также вы исследовали трассировку тупика, чтобы определить, что именно вы блокировали?

Вы можете сделать это, включив флаг трассировки 1204 . Или работает SQL Profiler. Это даст вам подробную информацию, которая даст вам знать, что за тупик (блокировки, потоки, параллельное соединение и т. Д.).

Проверьте эту статью на Обнаружение и устранение тупиков .

Еще один способ сделать аудит состоит в том, чтобы полностью отделить бизнес-транзакцию, отправив все события журналирования в очередь на уровне приложения, это минимизирует влияние журналирования на вашу бизнес-транзакцию, но, вероятно, очень большое для существующего приложения .

0 голосов
/ 06 июня 2018

У меня было такое же требование, когда мне нужно было записывать ошибки в таблицу ошибок, но я обнаружил, что откат их стирает.

Решил эту проблему, поместив ранее вставленные записи об ошибках в табличную переменную, вызвав Rollback, а затем вытолкнув (вставив) записи в таблицу.

Работает как талисман, но код запутанный, потому что он должен быть встроенным. Невозможно поместить ROLLBACK в хранимую процедуру, иначе будет получено сообщение «Количество транзакций после EXECUTE ...».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...