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

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

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

спасибо.

изменить, чтобы уточнить...

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

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

8 ответов


нет, он всегда совершал.

Если вы хотите откат, вам придется сделать это до 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 усечь таблицу или alter table или создать таблицу всегда вызывайте фиксацию.

Почему вы хотите откат, когда вы делаете усечь таблицу?


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

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

можно уточнить?

последующие 24 июня 2003 г. - 7 утра нас/Восточная:

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

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

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


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

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

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

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


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

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

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 like 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