Я читал, что некоторые devs/dbas рекомендуют использовать транзакции во всех вызовах базы данных, даже для вызовов только для чтения. Хотя я понимаю, что вставка/обновление в транзакции является преимуществом чтения внутри транзакции?Должна ли существовать транзакция для запросов на чтение?
ответ
Таким образом, вы получаете согласованное представление о базе данных. Представьте, у вас есть две таблицы, которые ссылаются друг на друга, но по какой-то причине вы делаете 2 выбирает ... в pseuodocode:
myRows = query(SELECT * FROM A)
moreRows = query(SELECT * FROM B WHERE a_id IN myRows[id])
Если между двумя запросами, кто-то меняет B, чтобы удалить некоторые строки, вы собираетесь иметь проблему.
Я бы сказал, что одна из основных целей транзакции заключается в том, чтобы предложить потенциал отката, если есть какие-либо проблемы, которые теряют силу при простом чтении.
Я обнаружил, что «транзакции» ведут себя по-разному на разных серверах SQL. В некоторых случаях запуск транзакции блокирует все другие соединения от возможности выполнять любой SQL до тех пор, пока транзакция не будет выполнена или отката (MS SQLServer 6.5). У других нет никаких проблем, и они блокируются только при наличии модификации (оракула). Блокировки могут даже расширяться, чтобы охватить только ваши изменения - блокировки ячеек/блокировки строк/блокировки страниц/блокировки таблиц.
Обычно я использую транзакции только тогда, когда целостность данных между несколькими операторами вставки/удаления/обновления должна поддерживаться. Даже тем не менее, я предпочитаю реализовать это, используя каскадные удаления с помощью DB, чтобы база данных делала это автоматически и атомарно.
Используйте транзакцию, если вы можете предвидеть ситуацию, когда вам нужно откатить несколько модификаций, но в противном случае база данных будет выполнять атомарные обновления без дополнительного кода для решения этой проблемы.
Я проверил это за последние несколько минут, так как это то, о чем я должен знать больше. Вот что я нашел.
Сделки были бы полезны вокруг выбора, если вы хотите заблокировать эту строку, когда человек читает записи и не хочет, чтобы она была изменена или прочитана. Например запустить эти запросы:
(в окне запроса 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) - позволит вам выбрать и заблокировать строки для обновлений, что поможет с параллелизмом.
Будьте осторожны с настольными подсказками. Если вы начнете применять их беспорядочно, ваша система будет медленно сканировать, если вы получите даже небольшое количество пользователей в вашем приложении. Это единственное, что я знал, прежде чем смотреть на это;)
Как и в случае с RoBorg, вы делаете SELECT для w/i транзакций, чтобы предотвратить чтение фантомных данных между операторами. BUT Важно отметить, что уровень изоляции транзакций по умолчанию в SQL Server - READ COMMITTED, который предотвратит только грязные чтения; чтобы предотвратить фантомные данные, вам придется использовать хотя бы ПОВТОРНЫЙ ПРОЧИТАТЬ. Msgstr "Использовать этот параметр только при необходимости."
Это не всегда так. Реализация вашей клиентской стороны может получить полный снимок таблицы и показать ожидаемые результаты. ADO.NET позволяет выполнять автономные запросы. – Kieveli 2008-11-21 14:27:20