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





Так вы получите единообразное представление о базе данных. Представьте, что у вас есть две таблицы, которые связаны друг с другом, но по какой-то причине вы делаете 2 выбора ... в псеводокоде:
myRows = query(SELECT * FROM A)
moreRows = query(SELECT * FROM B WHERE a_id IN myRows[id])
Если между двумя запросами кто-то изменит B, чтобы удалить несколько строк, у вас возникнет проблема.
На самом деле это зависит от множества вещей, включая конфигурацию вашего сервера. Был задан вопрос, почему вы помещаете SELECT в транзакцию ... вот почему.
+1 это очень четкое объяснение. Да, это зависит от других вещей (например, при использовании Hibernate или NHibernate объекты кэшируются после чтения), но изоляция - это один из четырех принципов транзакций, о котором нельзя забывать.
Я бы сказал, что одна из основных целей транзакции - предложить возможность отката в случае каких-либо проблем, что не работает при простом чтении.
Я обнаружил, что «транзакции» ведут себя по-разному на разных серверах SQL. В некоторых случаях запуск транзакции блокирует все другие соединения от возможности выполнения любого SQL до тех пор, пока транзакция не будет зафиксирована или откат (MS SQLServer 6.5). У других проблем нет, и они блокируются только тогда, когда есть модификация (оракул). Блокировки могут даже расширяться, чтобы охватить только ваши изменения - блокировки ячеек / блокировки строк / блокировки страниц / блокировки таблиц.
Обычно я использую транзакции только тогда, когда необходимо поддерживать целостность данных между несколькими операторами вставки / удаления / обновления. Тем не менее, я предпочитаю реализовать это с помощью определяемых DB каскадных удалений, чтобы база данных выполняла это автоматически и атомарно.
Используйте транзакцию, если вы можете предвидеть ситуацию, когда вы хотите откатить несколько модификаций, но в противном случае база данных будет выполнять атомарные обновления без дополнительного кода, чтобы справиться с этим.
Я проверял это последние несколько минут, так как это то, о чем я должен знать больше. Вот что я нашел.
Транзакции были бы полезны при выборе, если вы хотите заблокировать эту строку, пока человек читает записи, и не хотите, чтобы она изменялась или читалась. Например, запустите эти запросы:
(в окне запроса 1)
НАЧАТЬ ТРАНС ВЫБРАТЬ * ИЗ 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) - позволит вам выбрать и заблокировать строки для обновлений, что поможет с параллелизмом.
Будьте осторожны с подсказками в таблице. Если вы начнете применять их бессистемно, ваша система будет медленно сканировать, если вы получите даже небольшое количество пользователей в вашем приложении. Это единственное, что я знал, прежде чем разобраться в этом;)
Подобно тому, что сказал Роборг, вы должны выполнить SELECTS с транзакциями, чтобы предотвратить чтение фантомных данных между операторами. НО важно отметить, что уровень изоляции транзакции по умолчанию в SQL Server - READ COMMITTED, что предотвращает только грязное чтение; чтобы предотвратить фантомные данные, вам придется использовать как минимум REPEATABLE READ. «Используйте эту опцию только при необходимости».
Еще одна веская причина сохранения нескольких транзакций для чтения и для вставки - это случай, когда вы хотите вставить базу записей на основе данных, полученных из запроса выбора, и вы также хотите зафиксировать каждую вставленную строку X.
Две транзакции:
позволит вам сделать это правильно, в то время как с одной транзакцией, не разделяющей чтение и запись, не позволит вам выполнить фиксацию без потери читателя.
Это не всегда так. Ваша реализация на стороне клиента может сделать полный снимок таблицы и показать ожидаемые результаты. ADO.NET позволяет выполнять офлайн-запросы.