Есть ли разница между commit и rollback транзакции только выбирает?

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

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

7 ответов


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

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

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

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

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


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

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

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

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


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


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

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

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

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


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

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

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


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


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