【问题标题】:Isolation level for Select statements in transactions for the same SQL Server trigger/stored procedure?同一 SQL Server 触发器/存储过程的事务中 Select 语句的隔离级别?
【发布时间】: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。它将数据插入到名为Footable 中。然后触发器调用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


【解决方案1】:

MSDN 文档中很好地介绍了隔离级别:Transaction Isolation Levels,它们肯定会影响 SP 的运行方式。另外,昨天提到的,触发器中的SP可能看不到导致触发器的插入。

【讨论】:

  • 非常感谢您的反馈!我昨天测试了它,SP 能够看到插入到 INSTEAD OF 触发器中的数据。但是如果有 100 个插入语句,我将不得不进行压力测试并确认它是 100%。我很欣赏这个链接;我会仔细阅读它。我一直在研究隔离级别的复杂性。我的结论是,我可能会在 SP 中的 Select 语句遇到问题,但我不是 100% 确定,这就是我在这里提出问题的原因。根据您的帖子,我似乎需要小心使用 SP 中的 Select。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-22
  • 1970-01-01
  • 2010-12-24
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多