一部のDBMSで特定のDDLステートメントのロールバックが許可されないのはなぜですか?


21

最近、MySQL 「alter table」などのDDLのロールバックをサポートしていないことがわかりました。サポートしない技術的な理由はありますか?それは単に彼らにとって「面白くない」機能ですか?

編集:この比較が見つかりました。トランザクションDDLをサポートする多くのDBMSがあるようです


3
MySQLはトランザクション内でDDLを許可しません。DDLステートメントを実行する前に、警告なしで現在のトランザクション(このトランザクション内のすべての現在のDMLステートメント!)をコミットします。
フランクヘイケンス

まさに、いらいらするIMO :)
ジョリル

個人的には、Postgresで許可されていることに驚いてDROPRENAMEます。
ジョー

1
データベース全体を削除しない限り、はい:)先ほど追加したリンクを参照してください
ジョリル

したがって、トランザクション内でDDLステートメントを許可しないのはOracleとMySQLのみです。この機能により、スキーマを簡単にデプロイできます。
マリアン

回答:


19

これがPostgreSQLで機能する理由は、システムカタログが通常のテーブルであるためです。そのため、たとえば、新しい関数を作成するには、pg_procテーブルに行を挿入するだけで、列のデフォルト値を変更するにはpg_attrdef、などで行を更新するだけで済みます。とにかくテーブルはトランザクションであるため、そのように動作させないためには、ほとんど邪魔にならないようにする必要があります。(多くの苦痛を伴う実装の詳細はここでは省略しました。;-))

他のデータベースエンジンは、カスタムの内部構造を使用してシステムカタログ情報を表すと、ソースコードを知らないと思います。そのため、トランザクションDDLを機能させるために、余分な労力を費やす必要があります。おそらく、彼らにとって優先事項ではないようです。

これの裏側は、これがPostgreSQLのメジャーバージョンアップグレードが非常に苦痛な理由であるということです。他の製品は、おそらく変更と更新を念頭に置いて内部メタデータ構造を設計できるため、新しいメジャーバージョンへのアップグレードに問題はありません。PostgreSQLでは、少なくともシステムをオンラインにしたままでは、システムカタログテーブルをシステムカタログテーブルの新しいバージョンのように突然変更する方法はありません。システムカタログにアクセスする必要があるためです。ほら


1
まあ、DBバージョンのアップグレードの容易さよりも常に一貫した状態のDBを好むでしょうが、それは意見の問題だと思います:)説明をありがとう!
ジョリル

これにより一部のデータベースの問題が説明される場合がありますが、システムカタログはOracleの通常のテーブルです。
リーリッフェル

10

ほとんどない?残念。

私は主にSQL Serverを使用していますが、実際に使用しています。オラクルはそうではないことは知っていますが、オラクルは異常かもしれないと思いました。

SQL Serverでは、単一のトランザクションで複数のDDLステートメントを実行できることを確信していますが、いくつかの制限もあると思います(これはすべて忘れていました)。必要に応じて、ほとんどのものを作成、変更、またはドロップし、ロールバックできます。Red-Gate SQL Compare(私が大好きなツール)はこれを利用しています。

これを行うことの問題は、トランザクションスコープがかなり興味深いものになることです。更新トランザクション(DDL)にシステムカタログを含めると、いくつかの本当に重要なロックを取得するリスクが生じ、システムカタログへのアクセスがブロックされる可能性があります。クエリでカタログ内のテーブルが見つからない場合、ユーザーは多くのことを実行できません。

ただし、最終的には、複数ステートメントのトランザクションにDDLを含めることができると便利です。

さらに便利なことに、SQL Server DDLコマンドTRUNCATE は複数ステートメントトランザクションの要素にもなります。ターゲットテーブルを(非常に高速に)切り捨てて構築し、結果に満足したらコミットを実行できます。何かがうまくいかない場合、ロールバックして出来上がり!、テーブルを邪魔したことがないようです。ログスペースも最小化されます。私はかなり頻繁にそれを利用しています。


2
SQL ServerのトランザクションバインドDDLの例を示す回答を次に示します。また、私はいつもTRUNCATEロールバックできないと思っていました。私は間違っていた。
ニックチャマス

5

SQL Serverでは、DDLステートメントをロールバックできます。ステートメントの最後で自動コミットを使用していません。他のDBMSではわかりませんが、Oracleでは同じことができないことを覚えています。これは各DBMSに固有のものであり、SQL標準がこれについて何を言っているのかわかりませんが、100%標準を実装しているプロデューサーはいないと思います。

SOにも同様の質問があります:トランザクション内で(SQL Server内で)複数のDDLステートメントを実行することは可能ですか?


5

Oracleはクエリ解析を共有しているため、1つのセッションで実行されるSELECT * FROM table_aは(通常)別のセッションと同じです。1つのセッションがテーブルに10個の列があると考え、別のセッションが11個あると考えた場合、それは壊れます。


興味深いことに、先日同様の問題が発生しました。アプリケーションは「ホット」デプロイ可能であるはずでしたが、新しいバージョンのテーブル構造を変更すると、JDBC PreparedStatementsを再起動する以外に再コンパイルする方法がありませんでした、そんなにたくさん!
ガイウス

2
余談ですが、11gR2バージョンには、ホットアップグレードを支援するエディションの概念が導入されています。事実上、既存の接続は1つのエディション(5つの列)を使用します。新しいセッションを開始するには、新しいエディションを開始し、列を追加し、新しいエディションを使用していくつかの新しい接続を開始します。すべての未処理のセッションが終了すると、古いエディションは不要になり、すべてが新しいエディションを使用します。ロールバックはありませんが、すべてが機能するまで新しいエディションに新しいアクティビティを追加することはできません。
ゲイリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.