私はDDLを発行するプログラムに取り組んでいます。CREATE TABLE
同様のDDLをロールバックできるかどうか知りたいのですが
- Postgres
- MySQL
- SQLite
- et al
各データベースがDDLを使用したトランザクションを処理する方法を説明します。
私はDDLを発行するプログラムに取り組んでいます。CREATE TABLE
同様のDDLをロールバックできるかどうか知りたいのですが
各データベースがDDLを使用したトランザクションを処理する方法を説明します。
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysisは、PostgreSQLの観点からこの問題の概要を提供します。
このドキュメントによると、DDLはトランザクションですか?
SQLiteにもトランザクションDDLがあるようです。SQLiteでステートメントを作成することができましROLLBACK
た。CREATE TABLE
そのCREATE TABLE
ドキュメントには、特別なトランザクションの「落とし穴」については触れられていません。
PostgreSQLには、ほとんどのデータベースオブジェクト(確かにテーブル、インデックスなどがありますが、データベース、ユーザーはありません)のトランザクションDDLがあります。ただし、実際には、すべてのDDLはACCESS EXCLUSIVE
ターゲットオブジェクトをロックし、DDLトランザクションが終了するまで完全にアクセスできなくなります。foo
また、すべての状況が完全に処理されるわけではありません。たとえば、別のトランザクションがテーブルを削除して置換テーブルを作成しているときにテーブルから選択しようとすると、ブロックされたトランザクションは新しいテーブルfoo
を見つけるのではなく、最終的にエラーを受け取ります。foo
(編集:これはPostgreSQL 9.3以前で修正されました)
CREATE INDEX ... CONCURRENTLY
例外的です。3つのトランザクションを使用して、同時更新を許可しながらテーブルにインデックスを追加するため、トランザクション内でそれ自体を実行することはできません。
また、データベース保守コマンドVACUUM
はトランザクションでは使用できません。
MySQLでは実行できないようですが、非常に馬鹿げていますが、本当です...(受け入れられた回答によると)
「InnoDBのCREATETABLEステートメントは単一のトランザクションとして処理されます。これは、ユーザーからのROLLBACKが、そのトランザクション中にユーザーが作成したCREATETABLEステートメントを元に戻さないことを意味します。」
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
いくつかの異なる方法を試しましたが、ロールバックしません。
回避策は、失敗フラグを設定し、クエリの1つが失敗した場合に「droptabletblname」を実行することです。
厳密には「ロールバック」とは言えませんが、データベースがそれをサポートするように構成されている場合、OracleではFLASHBACKコマンドを使用してこれらのタイプの変更を元に戻すことができます。
他の答えはかなり時代遅れのようです。
2019年現在: