У меня есть SQL Таблица сервера с целым столбцом Status
. Мой код обновляет Status
записи, а затем, через миллисекунды, снова обновляет ее до другого значения.
В этой таблице есть триггер, который вставляет запись в отдельную таблицу History
каждый раз, когда Status
значение изменяется.
В таблице History
есть столбцы для:
Id uniqueidentifier
: значение PK обновленной записи (примечание: НЕ внешний ключ - нам не нужна ссылочная целостность ) Status int
: новое значение состояния обновленной записи TimeUtc DateTime2(7)
: время обновления
Файл журнала NLog показывает, что мы делаем два отдельных вызова базы данных UPDATE
в закрытое, но разное время. Но когда мы смотрим в базу данных впоследствии, значение TimeUtc
для двух записей истории идентично микросекунде:
Id: CD83... Status: 4 TimeUtc: 2020-3-20 16:14:26.6952631
Id: CD83... Status: 5 TimeUtc: 2020-3-20 16:14:26.6952631
Почему это происходит? Чтобы сделать это еще более странным, иногда, когда мы запускаем параллельный код, две отдельные записи будут обновляться практически в одно и то же время, и все четыре записи истории будут иметь одну и ту же метку времени.
Id: CD83... Status: 4 TimeUtc: 2020-3-20 16:14:26.6952631
Id: CD83... Status: 5 TimeUtc: 2020-3-20 16:14:26.6952631
Id: 06EA... Status: 4 TimeUtc: 2020-3-20 16:14:26.6952631
Id: 06EA... Status: 5 TimeUtc: 2020-3-20 16:14:26.6952631
Мы используем ServiceStack OrmLite для обновления значений и документы говорят мне, что каждый вызов - это отдельная транзакция, которая (я думал) выдаст два отдельных события триггера, но, возможно, это неправильно. Похоже, SQL Сервер копирует события триггера и запускает их все сразу. Может ли ServiceStack OrmLite объединять вызовы внутри единой транзакции?
Вот определение триггера. Дайте мне знать, если понадобится больше деталей:
CREATE TRIGGER [dbo].[ChangeStatus]
ON [dbo].[TableWithStatus]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
-- On insert, or on update where status changed
INSERT INTO History
SELECT i.[Id], i.[Status], SYSUTCDATETIME()
FROM Inserted i
LEFT JOIN Deleted d ON i.Id = d.Id
WHERE i.[Status] IS NOT NULL
AND (d.[Status] IS NULL OR i.[Status] <> d.[Status])
END
GO
ADDENDUM: я обновил таблицу History четвертым полем (varchar) и обновил триггер, чтобы записать @@ SPID и CURRENT_TRANSACTION_ID () в это поле, разделив их двоеточие Вот что я получил:
Каждое обновление было выполнено в том же сеансе и отдельной транзакции, обе из которых я ожидал, но тогда это все еще не объясняет, почему записи имеют одинаковую отметку времени.