web-dev-qa-db-ja.com

クロスデータベーストランザクションを実行する場合、どのトランザクションログに情報が保存されますか?

次のスニペットがあるとします。

-- error checking omitted for brevity
begin tran

exec database1..my_stored_procedure
exec database2..my_other_stored_procedure

if (@@error <> 0)
  rollback

commit

トランザクション情報はどのデータベースのトランザクションログに挿入されますか?

database1のトランザクションログを再生しようとしても、そのDBにのみ影響を与えたとしても意味がないため、両方のログですべてのデータが取得されると思います。また、database1が存在しないサーバーではdatabase2のトランザクションログを再生できず、その逆も同様です。

..しかし、私は修正にオープンです!

8
Ian Kemp

トランザクションログは、ご想像のとおり、実行中のSQLステートメントを記録していません。代わりに、各データベースの生データへの変更を個別に記録しています。

あるデータベースのストアドプロシージャが、別のデータベースのトランザクションログで完全に機能している可能性があります。

... database1..my_stored_procedure AS 
BEGIN
INSERT INTO database2..table1 (col1) values (1);
  ^^ changes written to database2's tlog
INSERT INTO database2..table2 (col1) values (2);
  ^^ changes written to database2's tlog
END
^^ when this transaction is committed, COMMIT is recorded in database2's tlog

または、両方に変更を加えるために。

... database2..my_other_stored_procedure AS 
BEGIN
INSERT INTO database1..table1 (col1) values (1);
  ^^ changes written to database1's tlog
INSERT INTO database2..table1 (col1) values (2);
  ^^ changes written to database2's tlog
END
^^ when this transaction is committed, COMMIT is recorded in BOTH database1's and database2's tlog

トランザクションログに記録されるのは実際のデータ変更であり、それらを発生させたSQLステートメントではありません。各トランザクションログファイルへのエントリは完全に独立しています。ただし、トランザクションがコミットされると、COMMITが2つのログファイルに同時に書き込まれる場合を除きます。

複数のデータベースにわたって多数のストアドプロシージャを実行する大規模なトランザクションがある場合も、同じロジックが適用されます。トランザクションをCOMMITすると、COMMITはトランザクションに参加したすべてのデータベースのログに記録されます。

Database2のバックアップを復元し、database1がないサーバーでトランザクションログを再生することは完全に可能です。

この動作により、SQL Serverでのプロシージャとビューのレイアウト方法にある程度の柔軟性が与えられます。多くのデータベース管理者は、ストアドプロシージャ、特にメンテナンスプロシージャを、アプリケーション/ユーザーデータベースとは完全に別のデータベース(Adminなど)に保持し、メンテナンス操作の結果をそのデータベースに書き込みます。ありがたいことに、Admin全体にコピーする必要なく、ユーザーデータベースの1つを開発サーバーに復元することもできます。

12
Nathan Jolly