Eu tenho um requisito semelhante às discussões anteriores em:
- Escrevendo um esquema bancário simples: como devo manter meus saldos sincronizados com o histórico de transações?
- Gatilho em combinação com a transação
Eu tenho duas tabelas [Account].[Balance]
e [Transaction].[Amount]
:
CREATE TABLE Account (
AccountID INT
, Balance MONEY
);
CREATE TABLE Transaction (
TransactionID INT
, AccountID INT
, Amount MONEY
);
Quando houver uma inserção, atualização ou exclusão na [Transaction]
tabela, o [Account].[Balance]
deve ser atualizado com base no arquivo [Amount]
.
Atualmente eu tenho um gatilho para fazer este trabalho:
ALTER TRIGGER [dbo].[TransactionChanged]
ON [dbo].[Transaction]
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
IF EXISTS (select 1 from [Deleted]) OR EXISTS (select 1 from [Inserted])
UPDATE [dbo].[Account]
SET
[Account].[Balance] = [Account].[Balance] +
(
Select ISNULL(Sum([Inserted].[Amount]),0)
From [Inserted]
Where [Account].[AccountID] = [Inserted].[AccountID]
)
-
(
Select ISNULL(Sum([Deleted].[Amount]),0)
From [Deleted]
Where [Account].[AccountID] = [Deleted].[AccountID]
)
END
Embora isso pareça estar funcionando, tenho dúvidas:
- O gatilho segue o princípio ACID do banco de dados relacional? Existe alguma chance de uma inserção ser confirmada, mas o gatilho falhar?
- Minhas declarações
IF
eUPDATE
parecem estranhas. Existe alguma maneira melhor de atualizar a[Account]
linha correta?