2009-06-25 15 views
28

Me pregunto si es posible ejecutar múltiples instrucciones DDL dentro de una transacción. Estoy especialmente interesado en SQL Server, aunque las respuestas con otras bases de datos (Oracle, PostgreSQL al menos) también podrían ser interesantes.¿Es posible ejecutar múltiples instrucciones DDL dentro de una transacción (dentro de SQL Server)?

He estado haciendo algunos "CREATE TABLE" y "CREATE VIEW" para la tabla creada dentro de una transacción y parece haber algunas inconsistencias y me pregunto si los DDL no deberían hacerse dentro de la transacción. ..

Probablemente podría mover el DDL fuera de la transacción pero Me gustaría obtener alguna referencia para esto. Lo que he encontrado hasta aquí:

  • MSDN página Isolation Levels in the Database Engine dice claramente que hay restricciones en lo que las operaciones DDL se pueden realizar en una transacción explícita que se ejecuta en el aislamiento de instantánea - pero no estoy usando el aislamiento de instantánea y esto debería resultar como un error.
    • Esto podría interpretarse de modo que las operaciones DDL se puedan llevar a cabo en una transacción explícita bajo diferentes niveles de aislamiento?
  • Oracle® Database Gateway for SQL Server User's Guide#DDL Statementsafirma que sólo una instrucción DDL puede ejecutar en una transacción dada - es esto vale también para SQL Server utilizada directamente?

Para Oracle:

Si algo importa, estoy haciendo esto con Java a través del controlador JTDS JDBC.

b.r. Touko

Respuesta

1

Podría ser que en MS SQL, las transacciones implícitas se desencadenen cuando se ejecutan las sentencias DDL y DML. Si se pulsa varias veces este fuera de esta ayuda, utilice SET IMPLICIT_TRANSACTIONS

EDIT: otra posibilidad - No se pueden combinar CREATE VIEW con otras declaraciones en el mismo lote. CREATE TABLE está bien. Separe los lotes con GO.

EDIT2: PUEDE utilizar múltiples DDL en una transacción, siempre que se separen con GO para crear diferentes lotes.

+0

Estoy usando la conexión JDBC# setAutoCommit (falso) y las declaraciones DML no se realizan con las transacciones implícitas. Los resultados parecen ser más como que la tabla para crear la vista no siempre estaría allí o algo así. – Touko

+0

Para EDITAR: Eso podría ser, pero me gustaría tener alguna referencia a la documentación de SQL Server o algo así, ya sea que esté o no permitido. – Touko

+0

Utilicé este libro, mira si lo encuentras en línea? Microsoft® SQL Server® 2008 Fundamentos de T-SQL Imprimir ISBN-10: 0-7356-2601-4 Imprimir ISBN-13: 978-0-7356-2601-0 – Stuart

1

Para el caso general y IIRC, no es seguro asumir que las declaraciones DDL son transaccionales.

Es decir, hay una gran libertad de acción sobre cómo las alteraciones de esquema interactúan dentro de una transacción (suponiendo que lo haga). Esto puede ser por proveedor o incluso por la instalación particular (es decir, hasta el dba), creo. Por lo menos, no use un DBMS para suponer que otros tratarán las declaraciones DDL.

Edición: MySql es un ejemplo de un DBMS que no admite transacciones DDL en absoluto.Además, si tiene replicación/duplicación de base de datos, debe tener mucho cuidado de que el servicio de replicación (la replicación de Sybase sea la norma, créalo o no) realmente replicará la instrucción DDL.

4

Si está creando tablas, vistas, etc. sobre la marcha (que no sean variables de tabla o tablas temporales), es posible que realmente necesite replantear su diseño. Esto no es algo que normalmente debería suceder desde la interfaz de usuario. Incluso si debe permitir alguna personalización, las instrucciones DDL no deberían estar sucediendo al mismo tiempo que se ejecutan inserciones/actualizaciones/eliminaciones transaccionales. Es mucho mejor separar estas funciones.

Esto también es algo que necesita una dosis saludable de consideración y prueba de lo que sucede cuando dos usuarios intentan cambiar la estructura de la misma tabla al mismo tiempo y luego ejecutan una transacción para insertar datos. Hay algunas cosas realmente aterradoras que pueden suceder cuando permite a los usuarios hacer ajustes en la estructura de su base de datos.

También algunas declaraciones DDL siempre deben ser la primera declaración de un lote. Cuidado con eso también cuando los estés ejecutando.

+0

Tienes buen punto, desafortunadamente con este proyecto estoy forzado a este diseño de db heredado ... Estos lotes parecen ser una unidad de instrucciones SQL Server ... Probablemente estoy ejecutando todas mis declaraciones en lotes separados con JDBC hasta Lo quiero explícitamente ... al menos creo ... – Touko

+18

Me gustaría añadir que encontraría las transacciones DDL muy útiles para un conjunto diferente de circunstancias, no actualizando sobre la marcha, pero asegurando que las actualizaciones de esquema a una base de datos de producción nunca se dejen en un estado inconsistente. – Nathan

+6

O para la migración de esquemas cuando la aplicación administra totalmente la base de datos y el usuario se ha actualizado de una versión anterior de la aplicación a una posterior. Tales migraciones nunca deberían fallar, pero si lo hacen, es mejor si el DB se deja en el estado previo a la migración. –

13

Sé que la mayoría de las bases de datos tienen restricciones, pero Postgres no. Puede ejecutar cualquier creación de tabla numérica, cambios de columna y cambios de índice en una transacción, y los cambios no son visibles para la unidad de otros usuarios que COMMIT tiene éxito. ¡Así deberían ser las bases de datos! :-)

En cuanto a SQL Server, puede ejecutar DDL dentro de una transacción, pero SQL Server does not version metadata, y así los cambios serían visibles para los demás antes de que la transacción se confirme. Pero some DDL statements can be rolled back if you are in a transaction, pero para cuáles funcionan y cuáles no, deberá realizar algunas pruebas.

+2

Solo para responderme yo mismo con un seguimiento, dos años después ... Aunque SQL Server no proporciona transacciones aisladas para DDL, puede deshacer varias sentencias DDL que han sido parte de una transacción.Mi colega acaba de hacer una prueba en SQL Server 2008 R2: "Intenté crear una tabla, agregar una columna de clave principal, insertar en otra tabla, agregar una columna a otra tabla, insertar en eso y luego forzar un error con SQL no válido todo ¡retrocedió correctamente! ". Solo asegúrese de que cada declaración DDL esté en su propio lote (usando el separador GO). –

+1

¿Debería quitar, "No ejecute DDL en el servidor SQL mientras la base de datos está en uso"? Como en, normalmente está bien usar una transacción para DDL siempre que nada más esté leyendo la tabla (lo que significa que su sitio web debería estar inactivo mientras actualiza la base de datos, lo que probablemente debería hacer, de todos modos). – jpmc26

+0

Puedo confirmar que Ingres permite (al menos) cambios de columna como parte de una transacción CRUD más amplia. Probablemente no sea sorprendente dada la relación Postgres/Ingres. – Sepster

Cuestiones relacionadas