Eu tenho o seguinte gatilho para auditoria.
CREATE OR ALTER TRIGGER dbo.TR_MyTrigger ON dbo.Cust
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @EntityState AS SMALLINT;
SET @EntityState = (CASE
WHEN EXISTS(SELECT * FROM INSERTED) AND EXISTS(SELECT * FROM DELETED) THEN 3 -- Updated
WHEN EXISTS(SELECT * FROM INSERTED) THEN 4 -- Inserted
WHEN EXISTS(SELECT * FROM DELETED) THEN 2 -- Deleted
ELSE NULL END)
IF @EntityState = 4
BEGIN
UPDATE Cust
SET Created = GETDATE(), Updated = GETDATE()
FROM INSERTED I
WHERE Cust.BinId = I.BinId
END
ELSE IF @EntityState = 3
BEGIN
UPDATE Cust
SET Updated = GETDATE()
FROM INSERTED I
WHERE Cust.BinId = I.BinId
END
IF @EntityState <> 2
BEGIN
INSERT INTO AuditEntries (SomeColumns..)
SELECT SomeColumns..
FROM INSERTED I;
END
ELSE
BEGIN
INSERT INTO AuditEntries (SomeColumns..)
SELECT SomeColumns..
FROM DELETED I;
END
END;
Quando a gravação da chamada do cliente (Servidor de API) na tabela Cust
for concluída, a próxima chamada será inserida userIds
na AuditEntries
tabela.
Informação extra:
- Não existem outros gatilhos em nenhum lugar.
- O cliente usa o EntityFramework Core, portanto, o tempo em questão é após os
SaveChangesAsync()
retornos. - A chave primária da
AuditEntries
tabela é aROWVERSION
dedbo.Cust
A questão é : AuditEntries
a existência é garantida neste momento ou esta é uma corrida que preciso lidar?
Outras pesquisas:
Uma resposta para: Sql Triggers são síncronos ou assíncronos
UPDATE : O gatilho acima não entra em um loop via recursão direta em nenhuma operação de atualização devido à configuração padrão do T-Sql. Consulte: Gatilhos Recursivos
Encontrei um SO que responde à minha pergunta original: um gatilho em uma transação é acionado apenas quando a transação é confirmada?
DELTE o UPDATE do seu gatilho
Quando você exclui o gatilho UPDATE, os casos 4 e 3 não disparam o gatilho novamente.
Portanto, somente quando você INSERT ou DELETE, o gatilho é executado e atualiza Cust ou insere em AuditEntries
Com este AFTER UPDATE TRiGGER você criaria um loop.
então você deve escrever outro gatilho apenas para UPDATES, se precisar de um.
Para responder sua pergunta
O gatilho seria executado após o INSER ou DELETE do dbo.Cust e será executado completamente antes de iniciar outro comando, isso porque você define seu gatilho como FOR EACH STATEMENT
Como Exemplo
Cada etapa é concluída antes da próxima