すべてのデータ変更が、それらが含まれるトランザクションがロールバックされたときに元に戻されるのは本当ですか?
たとえば、ストアドプロシージャを100回実行したカーソルが各反復でテーブルを更新した場合、それらの更新はすべてロールバックされますか?
DDLステートメントはロールバックされますか?... DROP TABLEやCREATE VIEWなど? DROP DATABASEについてはどうですか?
PRINT "MESSAGE"のように特定のステートメントが実行されることは知っています。
私はまだどのような種類のイベントがまだ起こっているのかを理解しようとしています。
明示的なトランザクション内での実行が許可されているステートメント(つまり、BEGIN TRAN
、または天国は禁止IMPLICIT_TRANSACTIONS
はON
)です。ROLLBACK
の影響を受けない次の2つのみを認識しています(技術的にはどちらもある意味で「不正」)。
リンクサーバーとOPENQUERY
を介して実行されるステートメント(ループバックサーバー定義を使用して現在のインスタンスに接続している場合でも)。リンクサーバープロパティが "リモートプロシージャトランザクションプロモーション"disabled(現在のトランザクションに参加しようとしないようにするため)。
OPENQUERY
(1つのオプションを無効にした場合)は、個別の接続を確立するため機能します。 T-SQL内で別の接続を確立する他の同様の方法があります。 David Browneはコメントで、拡張ストアドプロシージャについて言及しました。 SQLCLRメソッドを(それらが公開されているT-SQLオブジェクトの種類に関係なく)そのリストに追加することもできますが、通常の/外部接続を行う場合に限り、および「enlist=false;
"を接続文字列に追加します。OLE Automationストアドプロシージャ(つまり、sp_OA*
)、しかし私はこれらについて100%確信していません。
明示的な変更ではないため、これが重要であるかどうかはわかりませんが、トランザクションが開始する前の状態に戻ることはできません(それが可能であるという意味もないため):Tibor Karasziは、 「アイデンティティ/シーケンス値の消費」が適格である可能性があるとコメントします。シーケンスが要求された値を返さないことをテストして確認しました。
同様に、ロールバックの影響を受けないデータベース状態であり、特にユーザーデータではない別の値は、現在/最後に使用されたタイムスタンプ値です(これはデータベースごとであり、システム変数 @@DBTS
;テストでも確認済み)
SESSION_CONTEXT
、これは各セッションのプロパティです。これらの同じ行に沿って、関連/類似 CONTEXT_INFO
ストアドプロシージャを100回実行したカーソルが各反復でテーブルを更新した場合、それらの更新はすべてロールバックされますか?
はい、これが明示的なトランザクションの目的です。ステートメントをアトミックな作業単位にグループ化することです。
DDLステートメントはロールバックされますか?... DROP TABLEやCREATE VIEWなど? DROP DATABASEについてはどうですか?
一部(たぶんほとんど)はい。いいえ。おそらくテストする必要があります。たとえば、ロールバックを行うDDLは次のとおりです。
USE [tempdb];
IF (OBJECT_ID(N'dbo.DropMe') IS NOT NULL)
BEGIN
DROP TABLE dbo.DropMe;
END;
CREATE TABLE dbo.DropMe (col1 INT);
BEGIN TRAN;
DROP TABLE dbo.DropMe;
ROLLBACK TRAN;
SELECT * FROM dbo.[DropMe];
ただし、逆に、明示的な(または暗黙的な)トランザクション内で実行できないDDLを次に示します。
CREATE DATABASE [DropMe];
BEGIN TRAN;
DROP DATABASE [DropMe];
/*
Msg 574, Level 16, State 0, Line XXXXX
DROP DATABASE statement cannot be used inside a user transaction.
*/
ROLLBACK;
したがって、上記の2つの例を参考にして、興味のある、または明確な回答が必要な他のステートメントに合わせて修正してください。
すべてのデータ変更が、それらが含まれるトランザクションがロールバックされたときに元に戻されるのは本当ですか?
はい。それがトランザクションの完全な感覚です。
たとえば、ストアドプロシージャを100回実行したばかりのカーソルが各反復でテーブルを更新した場合、それらの更新はすべてロールバックされますか?
これがすべての変更の定義です。
DDLステートメントはロールバックされますか?.
ステートメントによって異なります。 RTFMは、それを整理する唯一の方法です(つまり、コマンドごとに文書化されています)が、一般に、1つのトランザクション内のDDLとDMLは混在せず、GENERALでは、DMLが変更はAREトランザクション(フィールドの追加はトランザクションであり、すべての行がトランザクションを取得するか、まったく行わない)です。トランザクションサポートが制限されていると想定すると、はるかに効果的です。SQLサーバーのバージョンにも大きく依存します。ドロップデータベースのような非常に重いヒッター-物理ファイルは実際に削除されますが、「データベース内」では実行されません-データベースの削除は、マスターデータベースとシステム全体のトランザクションになります。
最近は通常、トランザクションでDMLを実行しますが、これは機能しますが、DMLの一部の変更はトランザクションで実行されないため、変更スクリプト(最初の行にコメントを含む)でトランザクションの折り返しを有効にする方法があります。
PRINT "MESSAGE"のように特定のステートメントが実行されることは知っています。
すべてのステートメントが実行されます。ロールバックは実行されていません。データの変更ではないため、PRINTをロールバックできないだけです;)
私はいくつかのテストを実行しました、ここに結果があります:
データベースの削除は、明示的な(トランザクションの開始...)トランザクション内では実行できません。
SQL Serverは以下をスローします:
DROP DATABASEステートメントは、ユーザートランザクション内では使用できません。
明示的なトランザクション内で問題なく実行できるドロップテーブル
ビューの作成-できますが、最初にbegin tran ...を実行し、次にcreate view ...を実行してから、ロールバックまたはコミットする必要があります。したがって、段階的に実行できますが、SQL Serverがスローするため、一度にすべてを実行することはできません。
「CREATE VIEW」はクエリバッチの最初のステートメントである必要があります。
したがって、カーソルがSP=を実行し、テーブル内のデータを更新し、明示的なトランザクション内にある場合、それはロールバックできます。ただし、カーソル/ SPが一部のデータベースもドロップする場合は、できません。ロールバックされない