2008-11-21 15 views
22

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

ответ

26

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

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

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

+0

Это не всегда так. Реализация вашей клиентской стороны может получить полный снимок таблицы и показать ожидаемые результаты. ADO.NET позволяет выполнять автономные запросы. – Kieveli 2008-11-21 14:27:20

0

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

1

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

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

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

1

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

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

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

BEGIN TRAN SELECT * FROM MyTable С (ROWLOCK XLOCK) WHERE ID = 1

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

SELECT * FROM MYTABLE WHERE 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) - позволит вам выбрать и заблокировать строки для обновлений, что поможет с параллелизмом.

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

3

Как и в случае с RoBorg, вы делаете SELECT для w/i транзакций, чтобы предотвратить чтение фантомных данных между операторами. BUT Важно отметить, что уровень изоляции транзакций по умолчанию в SQL Server - READ COMMITTED, который предотвратит только грязные чтения; чтобы предотвратить фантомные данные, вам придется использовать хотя бы ПОВТОРНЫЙ ПРОЧИТАТЬ. Msgstr "Использовать этот параметр только при необходимости."

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