我一直在想关于SQL Server数据库触发器的并发语义。我有一个数据库触发器,在更新表后运行。触发器将“dateModified”列设置为当前时间。这使我始终知道表的最新更新发生在X时。下面是它的样子:
ALTER TRIGGER base.TR_myTrigger ON base.myTable
AFTER INSERT, UPDATE AS
BEGIN
DECLARE @dateModified AS DATETIMEOFFSET
SET @dateModified = SYSDATETIMEOFFSET()
UPDATE base.myTable
Set dateModified = @dateModified
WHERE id in (SELECT DISTINCT(id) FROM inserted)
END
在我的场景中,表可以随时由任意数量的线程更新。这个触发器在多线程环境中是否安全?如果线程A更新了表,并且线程B在之后立即从中读取,那么B是否会看到具有A更新但没有触发更新的表的状态?或者触发器是否保护表不被读取,直到执行了所有操作+触发器?
对于使用SQL数据库触发器在幕后发生的事情的任何见解将不胜感激。谢谢!
答案 0 :(得分:2)
如果线程A更新了表,并且线程B在之后立即从中读取,那么B是否会看到具有A更新的表的状态,但也没有触发更新?或者触发器是否保护表不被读取,直到执行了所有操作+触发器?
归结为:基础操作和触发操作是作为原子单元处理还是分开?答案是:原子。也就是说,您永远不会看到插入或更新的结果(在您的情况下),并且看不到通过触发器处理的dateModified列。也就是说,它们都在一次交易中提交。来自the documentation:
触发器和触发它的语句被视为单个事务......
答案 1 :(得分:0)
触发器没有任何关于并发性的特殊属性。它们就像你手动执行该代码一样运行。
您的触发器是安全的,因为您读取和写入的所有行都已被触发DML X锁定。