Можно ли выбрать данные во время транзакции? - PullRequest
3 голосов
/ 17 декабря 2009

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

Я использую LinqToSQL и SQL Server 2005 (dev) / 2008 (prod).

Ответы [ 3 ]

1 голос
/ 17 декабря 2009

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

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

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

Вот код C # для установки уровня изоляции области транзакции.

TransactionOptions option = new TransactionOptions();        
options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;        
using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required, options)
{
    // Code within transaction
}

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

Другой конец шкалы - это уровень изоляции, такой как SERIALIZABLE, который гарантирует, что ваша транзакция полностью изолирована до тех пор, пока она не будет завершена.

0 голосов
/ 17 декабря 2009

В дополнение к уже предоставленному совету я настоятельно рекомендую вам взглянуть на модели изоляции моментальных снимков. Хорошее обсуждение на Использование изоляции снимков . Включение «Read Committed Snapshot ON» в базе данных может облегчить множество конфликтов, поскольку читатели больше не блокируются авторами. Поскольку чтение по умолчанию выполняется в режиме изоляции с фиксацией на чтение, этот простой переключатель параметров базы данных имеет немедленные преимущества и не требует никаких изменений в приложении.

Бесплатного обеда не существует, так что это по цене, в данном случае это дополнительная нагрузка на базу данных tempdb, см. Использование ресурсов управления версиями строк .

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

0 голосов
/ 17 декабря 2009

Да, по умолчанию TransactionScope заблокирует таблицы, участвующие в транзакции. Если вам нужно прочитать во время транзакции, введите другой TransactionScope с TransactionOptions IsolationLevel.ReadUncommitted:

TransactionScopeOptions = new TransactionScopeOptions();
options.IsolationLevel = IsolationLevel.ReadUncommitted;
using(var scope = new TransactionScope(
    TransactionScopeOption.RequiresNew, 
    options
) {
    // read the database
}

С LINQ-to-SQL DataContext:

// db is DataContext
db.Transaction = 
    db.Connection.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);

Обратите внимание, что есть разница между System.Transactions.IsolationLevel и System.Data.IsolationLevel. Да, вы правильно прочитали.

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