web-dev-qa-db-ja.com

トランザクションのトリガーは、トランザクションがコミットされたときにのみ起動しますか?

私は開発者ですが、次の質問については、dbaコミュニティに問い合わせます。

C#で統合テストを書いています。このテストでは、最初にトランザクションを開始し、テストが成功したか失敗したかに関係なく、常にロールバックするため、データベースには何もコミットされません。

トランザクションを開始した後、テーブルに何かを挿入します。このテーブルには挿入のトリガーがありますが、このトリガーはトランザクションをコミットしたときにのみトリガーされるという印象を受けます。

これは本当ですか?

トランザクション内でトリガーを起動する方法はありますか?

したがって、実行時に何が起こるかは次のとおりです。

  • テーブルAに挿入
    • トリガーが起動され、テーブルBに挿入されます

私のテストで何が起こるか:

  • オープントランザクション
  • テーブルAに挿入
  • テーブルBをチェックします->挿入は実行されていません
4
Peter

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
7
Scott Hodgin

トリガーにはさまざまなタイプがあります。いくつかはINSERTの前であっても起動します

ただし、いずれの場合でも、INSERTと関連するトリガーは同じトランザクションの一部であるため、すべてのトランザクションが実行される前、またはすべてのトランザクションが実行された後にのみ、データベースのステータスが表示されます。

ただし、テストではEntity Frameworkを使用しているため、データベースに送信される前に、メモリ内のオブジェクトを調べている可能性があります。したがって、データを永続化するためにcontext.SaveChanges()を呼び出していないときに(挿入される)オブジェクトにクエリを実行できます。これは、データベースへのINSERT(およびトリガーの実行)を取得するときです。

これをテストするには、SQL Server Management Studioからクエリを実行します。両方のテーブルにデータがあるか、どちらにもないはずです。

2
Bruno Guardia

トリガーは、作成されたイベントに対してすぐに起動します。操作が明示的なトランザクションでラップされているかどうかはこれに影響しません。

Table Bで何かを表示できるかどうかは、すべてwhenCheck table B --> insert hasn't been executedに依存します。 「チェック」がROLLBACKの後に発生した場合、orの後にConnection.CloseおよびConnection.Openの後に-接続プールを使用して同じConnectionIDを取得した場合でも- -コミットされていないトランザクションのROLLBACKが発生するため、トリガーの「効果」は、ロールバックされたときに表示されません。

0
Solomon Rutzky