Non istruzioni DDL sempre dare un implicito commettere, o si può ottenere un rollback implicito?

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

  •  06-09-2019
  •  | 
  •  

Domanda

Se siete a metà strada attraverso una transazione e di eseguire un'istruzione DDL, come ad esempio il troncamento un tavolo, poi commit della transazione.

Mi chiedevo se questo è sempre stato così e, per definizione, o c'è un ambiente nascosto da qualche parte che avrebbe rollback la transazione invece di commettere.

Grazie.

Modifica per chiarire ...

Non sto cercando di far ritirare dopo un troncare. Voglio solo confermare che le dichiarazioni già effettuati sono assolutamente sempre che va da impegnare prima di un DDL. Voglio solo per assicurarsi che non ci sia una proprietà di sistema da qualche parte che qualcuno potrebbe impostare di distruggere il mio codice.

Capisco la necessità di impegnare prima e dopo una DDL, ma concettualmente avrei pensato la stessa esigenza di coerenza potrebbero essere raggiunto con un rollback prima che il DDL e un commit dopo.

È stato utile?

Soluzione

No, sarà sempre commettere.

Se si desidera eseguire il rollback, dovrete farlo prima che il DDL.

Se si desidera isolare il DDL dalla transazione esistente, allora si dovrà eseguire nella sua propria, transazione separata.

Altri suggerimenti

DDL fa un commit prima di eseguire e dopo la sua esecuzione.

Si stesso link da Cookie, ma questo è un altro aspetto della stessa questione. E 'fondamentale per capire che non è solo un commit, ce ne sono due e si verificano subito prima e subito dopo.

In realtà si impegnerà se può. Se non può commettere con successo, il DDL fallirà. Un modo per fermarlo commettere è avere un vincolo differito violato.

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

Quindi, se si vuole evitare un implicito commit, hanno una tabella fittizia con un vincolo differito. Inserire una riga violando in esso, ed è possibile assicurarsi che la transazione non può essere commesso fino alla risoluzione che la violazione (ad esempio riga eliminata).

Un Tavolo troncare o un ALTER TABLE o Tavolo creare non sempre causa un commit.

Perché vuoi far ritirare quando si esegue una tabella troncare?

Qui è un articolo AskTom che può aiutare. Dall'articolo:

"Mi chiedevo perché istruzioni DDL non vengono eseguite all'interno di una transazione autonoma (come sequenze fanno), in modo da influenzare avrebbe't qualsiasi transazione utente in attesa di ...

Può chiarire?

Followup 24 giu 2003 - 07:00 US / orientale:

che sarebbe come "confusione", come non fare in questo modo. in ogni caso, si dispone di ATRANS quindi se si vuole, è possibile. "

Quindi, se si ha realmente bisogno, si può attaccare il vostro DDL all'interno di una transazione autonoma e fare quello che vuoi.

EDIT: Linea di fondo è che se non si va a lunghezze espliciti a "sovvertire" Oracle, DDL sta per eseguire un commit. Detto questo, se è assolutamente necessario che un commit viene eseguita a un certo punto, perché non basta eseguire in modo esplicito?

DDL dichiarazioni sempre esegue commit automatico, dopo l'esecuzione.

Se si desidera eseguire il rollback in caso di guasto (in lato server), allora è possibile impostare alcuni flag per indicare l'errore e intraprendere l'azione appropriata.

ad esempio: se è stato creato un tabella1 tavolo. e allo stesso tempo si sta inserendo un record nella tabella.

ma inserzione è fallita per qualsiasi ragione (flag impostato = true) Then in quel caso non è possibile eseguire il rollback come creare dichiarazione è una dichiarazione DDL, in modo da poter annullare le modifiche nel database facendo cadere la tabella (tabella 1) a seconda del valore della bandiera, dalla dichiarazione di goccia.

Sono d'accordo con DCookie e Tom sulla transazione autonoma. Stavo per affermarlo anche.

Esempio pseudocodice:

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

Non vedo questo come essendo molto utile però. Se il DML iniziale e il DDL toccano allo stesso tavolo / oggetto, non sta andando a lavorare. Otterrete contesa quando si tenta di eseguire il DDL. Esattamente come qualsiasi due operazioni che bloccano a vicenda. E se sono oggetti indipendenti, credo che non vedo perché le questioni di ordine di esecuzione.

"Sempre / mai" è troppo forte. Per esempio DDL come CREATE PRIVATE TEMPORARY TABLE da Oracle 18c non COMMIT la transazione.

scenario normale:

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

Ma se si crea tavolo privato:

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

db <> violino demo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top