Есть ли разница между фиксацией и откатом в транзакции, в которой есть только выбор? - PullRequest
20 голосов
/ 13 октября 2008

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

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

Ответы [ 7 ]

12 голосов
/ 13 октября 2008

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

Oracle имеет как журнал, так и пространство отката. Журнал транзакций накапливает блоки, которые позже записываются авторами БД. Поскольку они асинхронные, почти ничего не связанное с записывающим устройством БД не повлияет на вашу транзакцию (если очередь заполняется, возможно, вам придется подождать.)

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

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

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

8 голосов
/ 13 октября 2008

Я согласен с предыдущими ответами, что в этом случае нет разницы между COMMIT и ROLLBACK. Может быть незначительная разница во времени ЦП, необходимом для определения того, что нет ничего для COMMIT, по сравнению с временем ЦП, необходимым для определения того, что нет ничего для ROLLBACK. Но, если разница незначительна, мы можем спокойно об этом забыть.

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

Если клиент запускает транзакцию, выполняет запрос, выполняет COMMITor ROLLBACK, затем запускает вторую транзакцию и выполняет второй запрос, нет никакой гарантии, что второй запрос будет иметь то же состояние базы данных, что и первый запрос. Иногда поддержание единого согласованного представления данных имеет существенное значение. Иногда получение более актуального представления данных имеет существенное значение. Это зависит от того, что вы делаете.

Я знаю, я знаю, ОП не задавал этот вопрос. Но некоторые читатели могут спросить об этом в глубине души.

3 голосов
/ 14 октября 2008

В документации указано, что:

  • Oracle рекомендует явно отключить каждую транзакцию в своих прикладных программах с помощью оператора COMMIT или ROLLBACK, включая последнюю транзакцию, перед отключением от базы данных Oracle. Если вы явно не фиксируете транзакцию и программа аварийно завершает свою работу, то последняя незафиксированная транзакция автоматически откатывается. Обычный выход из большинства утилит и инструментов Oracle приводит к фиксации текущей транзакции. Обычный выход из программы прекомпиляции Oracle не фиксирует транзакцию и использует базу данных Oracle для отката текущей транзакции.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_4010.htm#SQLRF01110

Если вы хотите выбрать одно или другое, то вы можете сделать то же самое, что ничего не делать, и просто совершить это.

3 голосов
/ 13 октября 2008

В общем случае COMMIT намного быстрее, чем ROLLBACK, но в случае, если вы ничего не сделали, они фактически одинаковы.

1 голос
/ 22 октября 2008

Хорошо, мы должны принять во внимание то, что SELECT возвращает в Oracle. Есть два режима. По умолчанию SELECT возвращает данные так, как они выглядели в тот самый момент, когда оператор SELECT начал выполняться (это поведение по умолчанию в режиме изоляции READ COMMITTED, режиме транзакций по умолчанию). Таким образом, если после выполнения команды SELECT был выполнен UPDATE / INSERT, он не будет виден в наборе результатов.

Это может быть проблемой, если вам нужно сравнить два набора результатов (например, дебетовую и кредитную стороны приложения главной книги). Для этого у нас есть второй режим. В этом режиме SELECT возвращает данные в том виде, в каком они выглядели в момент начала текущей транзакции (поведение по умолчанию для уровней изоляции READ ONLY и SERIALIZABLE).

Так, по крайней мере, иногда необходимо выполнить SELECT в транзакции.

0 голосов
/ 07 апреля 2011

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

0 голосов
/ 13 октября 2008

Так как вы не делали DML, я подозреваю, что не будет разницы между COMMIT и ROLLBACK в Oracle. В любом случае делать нечего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...