Должна ли быть транзакция для запросов на чтение? - PullRequest
24 голосов
/ 21 ноября 2008

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

Ответы [ 5 ]

27 голосов
/ 21 ноября 2008

Таким образом, вы получаете согласованное представление о базе данных. Представьте, что у вас есть две таблицы, которые связаны друг с другом, но по какой-то причине вы делаете 2 выбора ... в псевдокоде:

myRows = query(SELECT * FROM A)
moreRows = query(SELECT * FROM B WHERE a_id IN myRows[id])

Если между двумя запросами кто-то изменит B, чтобы удалить несколько строк, у вас возникнет проблема.

3 голосов
/ 22 ноября 2008

Подобно тому, что сказал Роборг, вы выполняете SELECTS w / i транзакции, чтобы предотвратить чтение фантомных данных между операторами. НО важно отметить, что уровень изоляции транзакций по умолчанию в SQL Server - READ COMMITTED, что предотвращает только грязное чтение; для предотвращения фантомных данных вы должны будете использовать как минимум REPEATABLE READ. «Используйте эту опцию только при необходимости.»

http://msdn.microsoft.com/en-us/library/ms173763.aspx

1 голос
/ 21 ноября 2008

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

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

(в окне запроса 1)

НАЧАТЬ ТРАН SELECT * FROM MYTABLE с (ROWLOCK XLOCK) ГДЕ ID = 1

(в окне запроса 2)

ВЫБРАТЬ * ИЗ MYTABLE ГДЕ ID = 1

(окно запроса 2 не вернет результаты, пока вы не запустите его в окне 1)

COMMIT TRAN

Полезные ссылки:

http://msdn.microsoft.com/en-us/library/aa213039.aspx

http://msdn.microsoft.com/en-us/library/aa213026.aspx

http://msdn.microsoft.com/en-us/library/ms190345.aspx

Моя цель состояла в том, чтобы получить что-то, чтобы заблокировать - и это наконец заработало после добавления туда XLOCK. Просто использование ROWLOCK не работало. Я предполагаю, что он выдавал общую блокировку (и данные были прочитаны) .. но я все еще исследую это.

Добавление - WITH (UPDLOCK ROWLOCK) - позволит вам выбрать и заблокировать строки для обновлений, что поможет с параллелизмом.

Будьте осторожны с табличными подсказками. Если вы начнете применять их беспорядочно, ваша система замедлится до ползания, если в вашем приложении будет даже небольшое количество пользователей. Это единственное, что я знал до того, как заглянул в это;)

1 голос
/ 21 ноября 2008

Я обнаружил, что «транзакции» ведут себя очень по-разному на разных серверах SQL. В некоторых случаях запуск транзакции блокирует все другие подключения от возможности выполнения любого SQL до тех пор, пока транзакция не будет зафиксирована или откатана (MS SQLServer 6.5). Другие не имеют никаких проблем, и блокируются только тогда, когда есть модификация (оракул). Блокировки могут даже расширяться, чтобы охватывать только ваши изменения - блокировки ячеек / блокировки строк / блокировки страниц / блокировки таблиц.

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

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

0 голосов
/ 21 ноября 2008

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

...