Уровень изоляции таблицы SQL Server и проблема блокировки - PullRequest
1 голос
/ 11 июля 2009

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

  1. На уровне изоляции SQL Server по умолчанию (чтение зафиксировано), после чтения каждой строки, строка будет разблокирована;

  2. Если я подниму уровень изоляции до повторяемого чтения, блокировка (на всю таблицу? Или какую-то другую блокировку уровня?) Будет удерживаться до конца цикла while?

например:.

SqlCommand cmd = conn.CreateCommand();

cmd.CommandText= "select operation_id, operation_code, product_id, quantity
from dbo.operations where processed=0";

reader=cmd.ExecuteReader();

while (reader.Read())    
{
   // some operations
}

спасибо заранее, George

Ответы [ 3 ]

1 голос
/ 11 июля 2009
1 голос
/ 11 июля 2009

При повторяемом чтении или в сериализуемых уровнях изоляции блокировки строк, полученные с помощью SELECT, будут удерживаться до тех пор, пока транзакция не совершит , а не до конца цикла. Если вы не укажете явную транзакцию, то оператор SELECT запустит неявную транзакцию, которая будет автоматически зафиксирована после завершения инструкции SELECT. Это не тот момент, когда завершается цикл while, цикл выполняется на клиенте, и оператор SELECT может завершиться на сервере до завершения цикла.

Как сказал Митч, более высокие уровни изоляции имеют определенную цель, чтобы избежать фантомных чтений или неповторяющихся чтений. Один оператор SELECT в неявной транзакции с автоматической фиксацией не может требовать более высокого уровня изоляции. Эти уровни вступают в силу только для транзакций с несколькими выписками, когда данные читаются несколько раз. Возможно, будет лучше, если вы объясните контекст операции, которую вы делаете, и почему вы беспокоитесь о блокировках, которые устанавливает этот SELECT?

1 голос
/ 11 июля 2009

1) Ваш первый пункт неверен: уровень изоляции по умолчанию для Read Committed означает, что не будет выполнено грязное чтение (хотя могут выполняться фантомные или не повторяемые чтения). Это не гарантирует, что отдельные строки заблокированы.

Неповторяемое чтение может произойти в следующей ситуации:

1. Transaction 1 begins
2. Transaction 1 read a row
3. Transaction 2 begins
4. Transaction 2 changes the value of the same row read by Transaction 1
5. Transaction 2 commits
6. Transaction 1 reads the row again. Transaction 1 has inconsistent data.

2) Уровень изоляции Repeatable Read означает, что вышеописанная ситуация не может возникнуть (хотя фантомное чтение все еще может). Фантомное чтение может произойти в следующей ситуации:

1. Transaction 1 begins
2. Transaction 1 read a row
3. Transaction 2 begins
4. Transaction 2 deletes the row read by Transaction 1
5. Transaction 2 commits. Transaction 1 can no longer repeat its initial read, 
   since the row no longer exists.

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

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