私は開発者ですが、次の質問については、dbaコミュニティに問い合わせます。
C#で統合テストを書いています。このテストでは、最初にトランザクションを開始し、テストが成功したか失敗したかに関係なく、常にロールバックするため、データベースには何もコミットされません。
トランザクションを開始した後、テーブルに何かを挿入します。このテーブルには挿入のトリガーがありますが、このトリガーはトランザクションをコミットしたときにのみトリガーされるという印象を受けます。
これは本当ですか?
トランザクション内でトリガーを起動する方法はありますか?
したがって、実行時に何が起こるかは次のとおりです。
私のテストで何が起こるか:
Entity Frameworkについては何も知りませんが、ローカルインスタンスに対してSQL Server Management Studioを使用する次の基本的なテストでは、テーブルdbo.Test1への挿入が完了するとトリガーが起動し、すぐに行を確認できますCOMMITを発行する前のdbo.Test2
USE [Test]
GO
IF OBJECT_ID('dbo.Test1', 'U') IS NOT NULL
DROP TABLE dbo.Test1
GO
IF OBJECT_ID('dbo.Test2', 'U') IS NOT NULL
DROP TABLE dbo.Test2
GO
CREATE TABLE [dbo].[test1](
[col1] [char](3) NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[test2](
[col1] [char](3) NULL
) ON [PRIMARY]
GO
CREATE TRIGGER dbo.Test1Trigger
ON dbo.Test1
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO dbo.Test2 select * from inserted
END
GO
begin transaction
insert into dbo.test1 (col1) values('abc')
select * from dbo.test2 --The row comes out of the select without issuing a commit
--insert into dbo.test2 (col1) values('xyz')
--commit
--select * from dbo.test2
--rollback
トリガーにはさまざまなタイプがあります。いくつかはINSERTの前であっても起動します
ただし、いずれの場合でも、INSERTと関連するトリガーは同じトランザクションの一部であるため、すべてのトランザクションが実行される前、またはすべてのトランザクションが実行された後にのみ、データベースのステータスが表示されます。
ただし、テストではEntity Frameworkを使用しているため、データベースに送信される前に、メモリ内のオブジェクトを調べている可能性があります。したがって、データを永続化するためにcontext.SaveChanges()を呼び出していないときに(挿入される)オブジェクトにクエリを実行できます。これは、データベースへのINSERT(およびトリガーの実行)を取得するときです。
これをテストするには、SQL Server Management Studioからクエリを実行します。両方のテーブルにデータがあるか、どちらにもないはずです。
トリガーは、作成されたイベントに対してすぐに起動します。操作が明示的なトランザクションでラップされているかどうかはこれに影響しません。
Table B
で何かを表示できるかどうかは、すべてwhenCheck table B --> insert hasn't been executed
に依存します。 「チェック」がROLLBACK
の後に発生した場合、orの後にConnection.Close
およびConnection.Open
の後に-接続プールを使用して同じConnectionIDを取得した場合でも- -コミットされていないトランザクションのROLLBACK
が発生するため、トリガーの「効果」は、ロールバックされたときに表示されません。