web-dev-qa-db-ja.com

主要なSQLデータベースでCREATE TABLEおよびALTER TABLEステートメントをロールバックすることは可能ですか?

私はDDLを発行するプログラムに取り組んでいます。 CREATE TABLEおよび同様のDDLをロールバックできるかどうかを知りたい

  • ポストグレス
  • MySQL
  • SQLite

各データベースがDDLでトランザクションを処理する方法を説明します。

103
joeforker

http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis は、PostgreSQLの観点からこの問題の概要を提供します。

このドキュメントによると、DDLはトランザクション対応ですか?

  • PostgreSQL-はい
  • MySQL-いいえ。 DDLは暗黙的なコミットを引き起こします
  • Oracle Database 11gリリース2以上-デフォルトではありませんが、エディションベースの再定義と呼ばれる代替が存在します
  • Oracleの古いバージョン-いいえ。 DDLは暗黙的なコミットを引き起こします
  • SQL Server-はい
  • Sybase Adaptive Server-はい
  • DB2-はい
  • Informix-はい
  • Firebird(Interbase)-はい

SQLiteにはトランザクションDDLもあるようです。 ROLLBACK a CREATE TABLE SQLiteのステートメント。そのCREATE TABLEドキュメントでは、特別なトランザクションの「落とし穴」については言及していません。

138
joeforker

PostgreSQLは、ほとんどのデータベースオブジェクト(データベース、ユーザーではなく、テーブル、インデックスなど)に対してトランザクションDDLを持っています。ただし、実際にはすべてのDDLがACCESS EXCLUSIVEターゲットオブジェクトをロックし、DDLトランザクションが完了するまで完全にアクセスできないようにします。また、すべての状況が完全に処理されるわけではありません。たとえば、別のトランザクションがそれを削除し、置換テーブルfooを作成している間にテーブルfooから選択しようとすると、ブロックされたトランザクションは最終的に受信します新しいfooテーブルを見つけるのではなくエラー。 (編集:これはPostgreSQL 9.3以前で修正されました)

CREATE INDEX ... CONCURRENTLYは例外です。3つのトランザクションを使用してインデックスをテーブルに追加し、同時に更新を許可するため、トランザクションでそれ自体を実行できません。

また、データベースメンテナンスコマンドVACUUMはトランザクションで使用できません。

28
araqnid

厳密に言うと「ロールバック」ではありませんが、OracleでFLASHBACKコマンドを使用して、これらのタイプの変更を元に戻すことができます(データベースがサポートされている場合)。

4
Dave Costa

MySQLでできない

「InnoDBのCREATE TABLEステートメントは単一のトランザクションとして処理されます。つまり、ユーザーからのROLLBACKは、そのトランザクション中にユーザーが作成したCREATE TABLEステートメントを元に戻しません。」

https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

いくつかの異なる方法を試してみましたが、単にロールバックしません。

回避策は、単純に失敗フラグを設定し、クエリの1つが失敗した場合に「drop table tblname」を実行することです。

2
Robert Sinclair

他の答えはかなり時代遅れのようです。

2019年現在:

  • Postgresは、多くのリリースでトランザクションDDLをサポートしています。
  • SQLiteは、多くのリリースでトランザクションDDLをサポートしています。
  • MySQLは 8.0以降のAtomic DDL (2018年にリリースされました)をサポートしています。
1
PaulMest