Qué instrucciones DDL siempre te dan un compromiso implícito, o se puede obtener una reversión implícita?

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

  •  06-09-2019
  •  | 
  •  

Pregunta

Si está a medio camino a través de una transacción y realizar una instrucción DDL, como truncar una tabla, a continuación, se confirma la transacción.

Me preguntaba si esto era siempre el caso y, por definición, o hay un ajuste escondido en alguna parte que haría rollback de la transacción en lugar de cometer.

Gracias.

Editar para aclarar ...

No estoy en busca de revertir después de un truncado. Sólo quiero confirmar que las declaraciones ya realizadas son absolutamente siempre va a estar comprometidos antes de que un DDL. Sólo quieren asegurarse de que no es una propiedad del sistema en alguna parte que alguien podría configurar para arruinar mi código.

Yo entiendo la necesidad de comprometerse antes y después de un DDL, pero conceptualmente habría pensado el mismo requisito de coherencia podría puede lograr con un retroceso antes de que el DDL y una confirmación después.

¿Fue útil?

Solución

No, siempre va a cometer.

Si desea restaurar, tendrá que hacerlo antes de que el DDL.

Si se desea aislar el DDL de su transacción existente, entonces usted tendrá que ejecutarlo en su propia, transacción por separado.

Otros consejos

Técnicamente DDL no una confirmación antes de ejecutar y después de que se ejecuta.

Sí mismo enlace de la galleta, pero este es un aspecto diferente de la misma cuestión. Es crucial comprender que no es sólo una confirmación, hay dos y de que sucedan justo antes y justo después.

En realidad, se comprometerá si se puede. Si no se puede cometer con éxito, el DDL fallará. Una forma de evitar que cometer es tener una restricción diferida violó.

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

Así que si desea evitar que cometa un implícito, tiene una mesa de maniquí con una restricción diferida. Insertar una fila violar en ella, y puede asegurarse de que la transacción no se puede confirmar hasta que se resuelva que la violación (por ejemplo fila eliminada).

A truncar la tabla o un alterar la tabla o un crear la tabla siempre causan una confirmación.

¿Por qué quiere deshacer cuando se hace una tabla truncada?

aquí es un artículo AskTom que pueden ayudar. Desde el artículo:

"Me preguntaba por qué instrucciones DDL no se ejecutan dentro de una transacción autónoma (como secuencias hacen), por lo que Afectan wouldn't cualquier transacción de usuario pendientes ...

Puede aclarar?

Seguimiento 24 de junio de 2003 - 07 a.m. EEUU / Este:

que sería como "confuso", como no hacerlo de esa manera. de todos modos, usted tiene ATRANS así que si usted quiere, se puede. "

Por lo tanto, si usted realmente necesita, puede pegarse el DDL dentro de una transacción autónoma y hacer lo que quiera.

EDIT: El fondo es que a menos que vaya a longitudes explícitas a "subvertir" Oracle, DDL se va a realizar un commit. Dicho esto, si a pesar de todo que necesita una confirmación se realiza en un momento determinado, ¿por qué no lo realiza de manera explícita?

DDL declaraciones siempre realiza comprometen auto, después de la ejecución.

Si usted quiere que rollback en caso de fallo (en el lado del servidor), entonces se puede establecer ciertas banderas para indicar el fallo y tomar la acción apropiada.

por ejemplo: si se ha creado una tabla tabla1. y al mismo tiempo va a insertar un registro en otra tabla.

pero la inserción ha fallado debido a alguna razón (bandera del set = true) .A continuación, en ese caso no se puede deshacer como crear instrucción es una instrucción DDL, por lo que puede deshacer los cambios en la base de datos al dejar caer la tabla (tabla 1) en función del valor de la bandera, por sentencia de descarte.

Estoy de acuerdo con DCookie y Tom acerca de la transacción autónoma. Iba a afirmar esto también.

Ejemplo pseudocódigo:

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

No veo esto como siendo muy útil sin embargo. Si el LMD inicial y el DDL tocan la misma mesa / objeto, no va a funcionar. Usted obtendrá la contención cuando se intenta realizar el DDL. Al igual que cualquiera de las dos operaciones de bloqueo entre sí. Y si son objetos independientes, supongo que no veo por qué los asuntos de orden de ejecución.

"Siempre / Nunca" es demasiado fuerte. Por ejemplo DDL como CREATE PRIVATE TEMPORARY TABLE de Oracle 18c no COMMIT su transacción.

Caso normal:

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

Sin embargo, si crea mesa privada:

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 <> violín demostración

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top