触发器 - 是否需要 BEGIN / COMMIT TRAN

Trigger - is it necessary BEGIN / COMMIT TRAN

我想像这样创建 INSTEAD OF 触发器:

CREATE TRIGGER [dbo].[DeleteCompany]
ON [dbo].[Company]
 INSTEAD OF DELETE
  AS 
  DECLARE @CompanyID int
  SELECT @CompanyID = deleted.CompanyID FROM deleted

  BEGIN TRAN
  DELETE FROM Project WHERE CompanyID = @CompanyID
  DELETE FROM CompanyPerson WHERE CompanyID = @CompanyID
  UPDATE PersonCompany SET CompanyID = null WHERE CompanyID = @CompanyID

  DELETE [Company]
     FROM DELETED D
     INNER JOIN [Company] T ON T.CompanyID = D.CompanyID
  COMMIT TRAN

所以,我可以肯定,这些操作是一个原子操作。但这是有道理的还是 TRIGGER 总是在事务内部执行?

此外,如果公司将在另一个 TRIGGER 中被删除,会发生什么情况:

CREATE TRIGGER [dbo].[DeleteSecurityLevel]
ON [dbo].[SecurityLevel]
 INSTEAD OF DELETE
  AS 
  DECLARE @SecurityLevelID int
  SELECT @SecurityLevelID = deleted.SecurityLevelID FROM deleted

  BEGIN TRAN
  DELETE FROM Company WHERE SecurityLevelId = @SecurityLevelID
  DELETE FROM CompanyRole WHERE SecurityLevelId = @SecurityLevelID
  ....

  DELETE SecurityLevel
     FROM DELETED D
     INNER JOIN SecurityLevel T ON T.SecurityLevelID = D.SecurityLevelID
  COMMIT TRAN

所以,触发器 DeleteSecurityLevel 正在删除公司并调用 DeleteCompany 触发器。如果每个触发器都有 BEGIN/COMMIT TRAM,它会在一个事务中吗?如果每个触发器都没有?

PS。我无法设置 "CASCADE DELETE" 因为数据库有一些类似的关系:

所以,尝试设置 CASCADE DELETE 会抛出这样的错误:

Introducing FOREIGN KEY constraint 'FK_Persons_Areas' on table 'Persons' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint or index. See previous errors.

所有DML 语句都在一个事务中执行。触发器内的 DML 将使用触发触发器的语句的事务上下文,因此触发器内部和外部的所有修改都是单个原子操作。

您不需要触发器内的显式事务,它们共享相同的事务工作区和触发器内的批处理以及调用它的操作一起提交或一起回滚

触发器始终在事务上下文中执行 - 每个 DML 语句都在事务中运行。由于隐式事务设置为在 SQL 服务器中自动提交,这通常从视图中隐藏。 如果您从触发器中发出回滚,这将(与回滚一样)回滚所有事务,无论是否嵌套。 通常,您不会在触发器内提交,除非(如在您注释掉的示例中)您明确打开嵌套事务。 如果您的问题还有其他方面,我无法从您发布的示例中找出它们是什么。虽然我一直很喜欢人们在提出 SQL 问题时发布实际 SQL,但有时一些评论或实际问题的要点列表会有所帮助。