Всегда ли инструкции DDL дают вам неявную фиксацию, или вы можете получить неявный откат?

StackOverflow https://stackoverflow.com/questions/730621

  •  06-09-2019
  •  | 
  •  

Вопрос

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

Мне было интересно, всегда ли это было так и по определению, или где-то скрыта настройка, которая бы Откат транзакция вместо фиксации.

Спасибо.

Отредактируйте, чтобы уточнить...

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

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

Это было полезно?

Решение

Нет, он всегда будет фиксироваться.

Если вы хотите выполнить откат, вам придется сделать это до DDL.

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

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

Технически DDL выполняет фиксацию ДО ее выполнения и ПОСЛЕ ее выполнения.

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

На самом деле он зафиксирует, ЕСЛИ СМОЖЕТ.Если он не сможет успешно зафиксировать, DDL завершится с ошибкой.Один из способов остановить его фиксацию - нарушить отложенное ограничение.

create table fred (id number);
alter table fred add constraint id_ck check (id >0) initially deferred;
insert into fred values (-1);
SQL> create table junk(val number);
create table junk(val number)
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02290: check constraint (GC_REF.ID_CK) violated
SQL> desc junk
ERROR:
ORA-04043: object junk does not exist

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

A усечь таблицу или изменить таблицу или a создать таблицу всегда вызывайте фиксацию.

Почему вы хотите выполнить откат при выполнении усечения таблицы?

Здесь это статья в AskTom, которая может помочь.Из статьи:

"Мне было интересно, почему инструкции DDL не выполняются внутри автономной транзакции (как это делают последовательности), поэтому они не повлияли бы на какую-либо ожидающую транзакцию пользователя...

Не могли бы вы пояснить?

Продолжение 24 июня 2003 года - 7 утра в США / Восточная:

это было бы так же "сбивающе с толку", как и не делать этого таким образом.в любом случае, у тебя есть atrans, так что, если ты захочешь, ты можешь."

Итак, если вам действительно нужно, вы можете вставить свой DDL в Автономную транзакцию и делать то, что вы хотите.

Редактировать:Суть в том, что если вы не пойдете на явные меры, чтобы "подорвать" Oracle, DDL выполнит фиксацию.Тем не менее, если вам абсолютно необходимо, чтобы фиксация была выполнена в определенный момент, почему бы просто не выполнить это явно?

Инструкции DDL всегда выполняют автоматическую фиксацию после выполнения.

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

например:если вы создали таблицу table1.и в то же время вы вставляете запись в другую таблицу.

но вставка не удалась по определенной причине (установить флаг= true).Тогда в этом случае вы не можете выполнить откат, поскольку оператор create является оператором ddl, поэтому вы можете отменить изменения в базе данных, удалив таблицу (table1) в зависимости от значения flag, с помощью оператора Drop.

Я согласен с DCookie и Томом по поводу автономной транзакции.Я собирался заявить и об этом.

Пример псевдокода:

Do some DML
Call autonomous function, that performs DDL
Do some more DML
rollback or commit all the DML - your choice

Однако я не считаю это очень полезным.Если исходные DML и DDL касаются одной и той же таблицы / объекта, это не сработает.Вы столкнетесь с разногласиями, когда попытаетесь выполнить DDL.Точно так же, как любые две транзакции блокируют друг друга.И если это независимые объекты, я думаю, я не понимаю, почему порядок выполнения имеет значение.

"Всегда / никогда" - это слишком сильно.Например, DDL, подобный CREATE PRIVATE TEMPORARY TABLE из Oracle 18c не будет COMMIT ваша транзакция.

Обычный сценарий:

CREATE TABLE t(i INT);
INSERT INTO t(i) VALUES(21);

CREATE TABLE x(i INT);   -- same for CREATE GLOBAL TEMPORARY TABLE y(i INT); 
ROLLBACK;

SELECT * FROM t;
-- Output:
-- 21

Но если вы создадите приватную таблицу:

CREATE TABLE t(i INT);
INSERT INTO t(i) VALUES(21);

CREATE PRIVATE TEMPORARY TABLE ORA$PTT_temp(i INT);  
-- or
CREATE PRIVATE TEMPORARY TABLE ORA$PTT_tab
AS
SELECT 1 AS c FROM dual;

ROLLBACK;
SELECT * FROM t;
-- Output:
-- no data found

дб<> демо-версия скрипки

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top