Должна ли быть транзакция для запросов чтения?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
40
0
14 377
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

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

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

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

Это не всегда так. Ваша реализация на стороне клиента может сделать полный снимок таблицы и показать ожидаемые результаты. ADO.NET позволяет выполнять офлайн-запросы.

Kieveli 21.11.2008 17:27

На самом деле это зависит от множества вещей, включая конфигурацию вашего сервера. Был задан вопрос, почему вы помещаете SELECT в транзакцию ... вот почему.

Greg 21.11.2008 17:37

+1 это очень четкое объяснение. Да, это зависит от других вещей (например, при использовании Hibernate или NHibernate объекты кэшируются после чтения), но изоляция - это один из четырех принципов транзакций, о котором нельзя забывать.

Dick Chesterwood 20.01.2011 11:43

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

Я обнаружил, что «транзакции» ведут себя по-разному на разных серверах 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. «Используйте эту опцию только при необходимости».

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

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

Две транзакции:

  1. для чтения \ выбора.
  2. для вставки и зафиксируйте каждую X строку.

позволит вам сделать это правильно, в то время как с одной транзакцией, не разделяющей чтение и запись, не позволит вам выполнить фиксацию без потери читателя.

Другие вопросы по теме