【发布时间】:2016-05-19 14:13:12
【问题描述】:
这个问题与Is a stored procedure call inside a SQL Server trigger implictly thread safe and atomic? 有关,所以我不知道是否应该重新发布相同的代码。不管怎样,这就是交易。
就目前而言,SQL Server trigger 目前是 INSTEAD OF INSERT。它将数据插入到名为Foo 的table 中。然后触发器调用stored procedure。存储过程的一部分selects 插入Foo的最后一条记录:
-- New transaction in stored procedure
BEGIN TRANSACTION
...
DECLARE @FooID INT
SELECT
TOP 1 @FooID = ID
FROM
Foo
ORDER BY
ID DESC
...
END TRANSACTION
假设同时执行两个INSERT 语句(为简化起见,我们将两个INSERT 事务称为T1 和T2)。这是两个同时触发的调用。就我而言,触发器和存储过程都是atomic。
但是我需要为存储过程中的SELECTstatement 担心isolation 吗?是否保证插入的最后一条记录将被正确选择?或者,我是否会遇到 T1 选择 T2 记录,反之亦然的情况?
谢谢。
【问题讨论】:
-
为什么不编写插入以使用
OUTPUT子句,然后在触发器本地确定从该OUTPUT生成的最高ID并将值显式传递给存储过程?顺便说一句,您已经知道多行插入和更新是一回事,并且触发器只对此类语句调用一次,对吗? -
非常感谢。好吧,我这样做的一个原因是存储过程是通用的,因为它可以由触发器或其他应用程序调用。所以,我有点想做一个 write-once 方法。而且,是的,我知道多行和触发器。插入的数据来自表单,每次表单提交将是一个插入行。再次感谢您。
-
但是您的存储过程,就目前而言,是脆弱的。它是“猜测特定表的最近历史正是我为之而写并从那里开始的那个”。这真的是一个很好的界面吗?本质上,“最近的 ID 值”已经是该存储过程的 隐藏 参数
-
我明白了。好吧,我想,也许是因为 SP 在此处的触发器中和在事务中,所以这不是猜测而是确定的。看起来只是因为它在事务和触发器内部,并不意味着 Select 语句中的数据会保持一致,对吗?
标签: sql sql-server stored-procedures triggers transactions