Oracle грязное чтение

Я новичок в использовании базы данных Oracle 11g.

Я тестировал блокировки таблиц и строк с помощью SQL Developer.

У меня есть строка в моей таблице, как это:

  • id: 1
  • desc: ‘abc’

Я сделал обновление без коммита, чтобы изменить поле desc в 'zxc', В другой сессии я сделал выборку, которая вернула старую запись:

  • id: 1
  • desc: ‘abc’

Я думал, что это даст мне ошибку или что-то еще, потому что я не хочу видеть старые данные.

Наконец, когда я зафиксировал в другой сессии, я снова выполнил запрос во второй сессии и вернул мне зафиксированные данные.

Как я могу предотвратить чтение старых данных?

ОБНОВИТЬ:

Я читал об SQL «SELECT FOR UPDATE», и он не позволяет получить строку, которая не была зафиксирована, но, например, кто-то говорит мне о банках, поэтому я не уверен, что этот подход имеет хорошую производительность, а другая проблема связана с потерей соединения без фиксации. , Может быть, мне нужно использовать функцию или PLSQL, чтобы минимизировать потерянное соединение, на самом деле я использую скрипт PHP (Laravel Framework).

Заранее спасибо.

2

Решение

Вы видите нормальное поведение «прочитано совершено». Фиксация означает «я готов позволить остальному миру увидеть результаты моей транзакции». Если вы не фиксируете его, он не будет учитываться для других сеансов базы данных. То, что вы называете «старыми данными», является последними подтвержденными данными.

Плохо было бы, если бы вы могли видеть обновление до его фиксации, то есть уровень изоляции «read uncommitted». Транзакции существуют для того, чтобы вы могли вносить изменения в базу данных атомарно, чтобы запросы отображали согласованное состояние, а не полусырые изменения.

Например, может быть две таблицы: таблица «Заказы» и таблица «Элементы строки», где таблица «Заказы» содержит итоговую сумму для всех элементов строки, и когда я добавляю позицию, я хочу обновить для нее «Заказ» в той же транзакции. так что итоговая сумма отражает новую позицию. Я не хочу, чтобы другие пользователи могли видеть изменения в строке «Заказы» или новой позиции, не видя других изменений, я хочу, чтобы оба изменения стали видны вместе, поэтому я делаю изменения в транзакции.

4

Другие решения

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

Одной из причин фиксации только в конце транзакции, а не после каждого обновления или вставки строки, является упрощение ввода данных с ограничениями ссылочной целостности, где ограничения проверяются только в конце транзакции. Скажем, создан новый отдел, и у него есть менеджер. Вы создаете новую строку в таблице «отделы», но для этого требуется значение менеджера. Вы создаете строку «менеджер» в таблице «сотрудники», но для этого требуется отдел. Что ты делаешь первым? Ответ — это не имеет значения, так как целостность проверяется только в конце транзакции (вставляется в обе таблицы).

Теперь представьте, что вы настаивали на том, чтобы увидеть незафиксированные изменения. Новый отдел был добавлен в «отделы», но в нем есть NULL для менеджера в ограниченном столбце NOT NULL. Вы ДЕЙСТВИТЕЛЬНО хотите это увидеть? Вероятно, вы можете придумать себе три разных способа, которыми это может вызвать серьезные проблемы в ваших приложениях.

(Я пропустил здесь тонкости, такие как отложенные ограничения, и именно поэтому возможны сценарии, подобные приведенному выше, — это не точка моего ответа.)

0