2009-06-25 10 views
28

Je me demande s'il est possible d'exécuter plusieurs instructions DDL dans une transaction. Je suis particulièrement intéressé par SQL Server, même si les réponses avec d'autres bases de données (Oracle, PostgreSQL au moins) pourraient aussi être intéressantes.Est-il possible d'exécuter plusieurs instructions DDL dans une transaction (dans SQL Server)?

J'ai fait quelques "CREATE TABLE" et "CREATE VIEW" pour la table créée dans une transaction et il semble y avoir quelques incohérences et je me demande si les DDL ne devraient pas être faites dans la transaction. ..

Je pourrais probablement déplacer le DDL en dehors de la transaction mais Je voudrais obtenir une référence pour cela. Ce que j'ai trouvé jusqu'ici:

  • la page MSDN Isolation Levels in the Database Engine indique clairement que il y a des restrictions sur les opérations DDL peuvent être effectuées dans une transaction explicite qui est en cours d'exécution sous isolement de capture instantanée - mais je ne suis pas en utilisant l'isolement d'instantané et cela devrait entraîner une erreur.
    • Ceci pourrait être interprété de sorte que les opérations DDL puissent être exécutées dans une transaction explicite sous différents niveaux d'isolement?
  • Oracle® Database Gateway for SQL Server User's Guide#DDL Statements affirme que une seule instruction DDL peut être exécutée dans une transaction donnée - est-ce valable aussi pour SQL Server utilisé directement?

Pour Oracle:

Si cela compte quelque chose, je le fais avec Java via le pilote JDBC JDBC.

b.r. Touko

Répondre

1

Se pourrait-il que dans MS SQL, les transactions implicites soient déclenchées lorsque les instructions DDL et DML sont exécutées. Si vous appuyez sur cette off cette aide, utilisez SET IMPLICIT_TRANSACTIONS

EDIT: Une autre possibilité - Vous ne pouvez pas combiner CREATE VIEW avec d'autres déclarations dans le même lot. CREATE TABLE est ok. Vous séparez les lots avec GO.

EDIT2: Vous pouvez utiliser plusieurs DDL dans une transaction aussi longtemps que séparés par GO pour créer différents lots.

+0

J'utilise JDBC Connection # setAutoCommit (false) et les instructions DML ne sont pas effectuées avec des transactions implicites. Les résultats semblent plus être comme si la table pour créer la vue avec ne serait pas toujours là ou quelque chose. – Touko

+0

Pour EDIT: Cela pourrait être mais je voudrais une référence à la documentation SQL Server ou quelque chose si elle est ou n'est pas autorisé .. – Touko

+0

J'ai utilisé ce livre, voir si vous trouvez en ligne? Microsoft® SQL Server® 2008 Principes de base de T-SQL Imprimer ISBN-10: 0-7356-2601-4 Imprimer ISBN-13: 978-0-7356-2601-0 – Stuart

1

Pour le cas général et IIRC, il n'est pas prudent de supposer que les instructions DDL sont transactionnelles. C'est-à-dire qu'il y a beaucoup de marge de manœuvre sur la façon dont les modifications de schémas interagissent au sein d'une transaction (en supposant qu'elle le fasse). Cela peut être par le fournisseur ou même par l'installation particulière (c'est-à-dire, jusqu'à la dba) je crois. Donc, à tout le moins, n'utilisez pas un SGBD pour supposer que d'autres traiteront les énoncés DDL. Edit: MySql est un exemple de SGBD qui ne supporte pas du tout les transactions DDL.En outre, si vous avez une réplication/mise en miroir de base de données, vous devez faire très attention à ce que le service de réplication (la réplication de Sybase soit la norme, croyez-le ou non) va répliquer l'instruction DDL.

4

Si vous créez des tables, des vues, etc. à la volée (à l'exception des variables de table ou des tables temporaires), vous devrez peut-être vraiment repenser votre conception. Ce ne sont pas des choses qui devraient normalement se produire à partir de l'interface utilisateur. Même si vous devez autoriser certaines personnalisations, les instructions DDL ne doivent pas se produire en même temps que les insertions/mises à jour/suppressions transactionnelles. Il est préférable de séparer ces fonctions. C'est aussi quelque chose qui nécessite une bonne dose de considération et de tests quant à ce qui se passe lorsque deux utilisateurs essaient de changer la structure de la même table en même temps, puis d'exécuter une transaction pour insérer des données. Il y a des choses vraiment effrayantes qui peuvent arriver lorsque vous permettez aux utilisateurs de faire des ajustements à la structure de votre base de données.

Certaines instructions DDL doivent toujours être la première instruction d'un lot. Attention à cela aussi quand vous les exécutez.

+0

Vous avez un bon point, malheureusement, avec ce projet, je suis contraint à cette conception db héritage .. Ces lots semblent être une unité d'instructions SQL Server .. Probablement je cours toutes mes déclarations dans des lots séparés avec JDBC jusqu'à ce que Je le veux explicitement .. au moins je pense .. – Touko

+18

J'ajouterais que je trouverais les transactions DDL très utiles pour un ensemble de circonstances différent - pas de mise à jour à la volée, mais de s'assurer que les mises à jour de schéma à une base de données de production ne sont jamais laissées un état incohérent. – Nathan

+6

Ou pour la migration des schémas lorsque la base de données est entièrement gérée par l'application et que l'utilisateur a effectué une mise à niveau d'une version antérieure de votre application vers une version ultérieure. De telles migrations ne doivent jamais échouer, mais si c'est le cas, il vaut mieux que la base de données soit laissée dans l'état de pré-migration. –

13

Je sais que la plupart des bases de données ont des restrictions, mais pas Postgres. Vous pouvez exécuter des créations de table de nombres, des modifications de colonne et des modifications d'index dans une transaction, et les modifications ne sont pas visibles pour les autres unités que l'unité COMMIT réussit. Voilà comment les bases de données devraient être! :-)

Comme pour SQL Server, vous pouvez exécuter DDL à l'intérieur d'une transaction, mais SQL Server does not version metadata, et ainsi les modifications seraient visibles pour les autres avant que la transaction ne soit validée. Mais some DDL statements can be rolled back if you are in a transaction, mais pour ceux qui travaillent et ceux qui ne le font pas, vous devrez exécuter des tests.

+2

Juste pour répondre à mon moi avec un suivi, deux ans plus tard ... Bien que SQL Server ne donne pas de transactions isolées pour DDL, il peut annuler plusieurs instructions DDL qui ont fait partie d'une transaction.Mon collègue vient de faire un test sur SQL Server 2008 R2: "J'ai essayé de créer une table, d'ajouter une colonne de clé primaire, de l'insérer dans une autre table, d'insérer une colonne dans une autre table, de l'insérer dans une autre table roulé correctement! ". Assurez-vous simplement que chaque instruction DDL est dans son propre lot (en utilisant le séparateur GO). –

+1

Est-ce que l'enlèvement devrait être, "Ne pas exécuter DDL dans le serveur SQL pendant que la base de données est utilisée"? Comme dans, il est généralement acceptable d'utiliser une transaction pour DDL tant que rien d'autre ne lit la table (ce qui signifie que votre site Web devrait être arrêté pendant la mise à jour de la base de données, ce qui devrait probablement être le cas). – jpmc26

+0

Je peux confirmer Ingres permet (au moins) des changements de colonne dans le cadre d'une transaction CRUD plus large. Probablement pas surprenant étant donné la relation Postgres/Ingres. – Sepster

Questions connexes