2008-10-13 4 views
20

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

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

ответ

12

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

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

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

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

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

+5

Я не признаю это как описание того, как оракул работает вообще. Это похоже на общее описание, которое было применено к Oracle. Угадай, как работает Oracle, вряд ли будет хвалить. – 2008-10-13 22:16:50

+0

Oracle вызывает журнал «Файл журнала повтора». Он вызывает сегменты отката «Отменить табличное пространство». Вы знаете, что быстрее? Commit или rollback? – 2008-10-13 22:26:13

0

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

4

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

8

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

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

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

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

3

В документации говорится, что:

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

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

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

1

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

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

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

0

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