Уровень изоляции в транзакции Sql - PullRequest
9 голосов
/ 29 февраля 2012

Я реализовал SqlTransaction в c # для начала, фиксации и отката транзакции.Все идет хорошо, но у меня есть некоторые проблемы при доступе к тем таблицам, которые связаны во время транзакции.Я не смог прочитать таблицу во время транзакции (те таблицы, которые находятся в транзакции).При поиске по этому поводу я обнаружил, что это происходит из-за эксклюзивной блокировки.Любые последующие выборки этих данных, в свою очередь, должны ждать освобождения исключительной блокировки.Затем я прошел все уровни изоляции, предоставленные SqlTransaction, но он не работал.Итак, мне нужно снять исключительную блокировку во время транзакции, чтобы другой пользователь мог иметь доступ к этой таблице и мог читать данные.Есть ли способ добиться этого?Заранее спасибо.

Вот мой код C # для транзакции

try
{
  SqlTransaction transaction = null;                         
  using (SqlConnection connection=new SqlConnection(Connection.ConnectionString))
  {
       connection.Open();
       transaction=connection.BeginTransaction(IsolationLevel.Snapshot,"FaresheetTransaction");            
       //Here all transaction occurs   
       if (transaction.Connection != null)
       {     
               transaction.Commit();
               transaction.Dispose();
       } 
   }
}
catch (Exception ex)
{
   if (transaction.Connection != null)
       transaction.Rollback();
   transaction.Dispose();   
}   `                         

Этот код работает нормально, но проблема в том, что, когда я обращаюсь к данным таблиц (тех, к которым обращались во время транзакции)) во время транзакции.Доступ к таблицам осуществляется другими частями приложения.Поэтому, когда я пытался прочитать данные из таблицы, он выдает исключение.

Ответы [ 4 ]

15 голосов
/ 29 февраля 2012

Транзакция SQL по своей природе является ACID.В частности, именно «я» причиняет вам боль - это , предназначенное , чтобы другие соединения не видели несовместимое промежуточное состояние.

Отдельное соединение для чтения может выбрать игнорирование этого правила.с помощью подсказки NOLOCK или уровня изоляции READ UNCOMMITTED, но, похоже, вы хотите, чтобы соединение write не блокировало.Что ж, этого не произойдет.

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

Однако, IMO, вам лучше посоветовать:

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

Первое проще.

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

3 голосов
/ 29 февраля 2012

Попробуйте также выполнить чтение в транзакции и использовать уровень изоляции READ UNCOMMITTED.Это предотвратит блокировку чтения, но может привести к недопустимым результатам:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED    
BEGIN TRANSACTION

SELECT * FROM Table

COMMIT TRANSACTION

Существует ошибочное мнение, что работа с уровнями транзакций / изоляции имеет значение только при записи, хотя на самом деле она одинаково важна при чтении.

2 голосов
/ 29 февраля 2012

Проблема не в уровне записи в базу данных, а в уровне чтения значений.Вы пытаетесь прочитать значения, которые вставляются.Попробуйте изменить свой запрос на выбор следующим образом:

select * from your_table_with_inserts with (nolock)

однако этот переопределяет уровень изоляции текущей транзакции и может привести к грязному чтению.

Поэтому вопрос таков: если вы используете транзакцию навсе запросы или только вставить / обновить?

1 голос
/ 07 февраля 2014

@ AKASH88, SNAPSHOT уровень изоляции - это то, что вы ищете.

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

Убедитесь, что вы не просто включили SNAPSHOT для параметров базы данных, но также должны быть включены READ COMMITTED SNAPSHOT .

enter image description here

Это SQL Server 2008, поэтому пока неясно, поможет ли этот ответ: (

С наилучшими пожеланиями!

...