【问题标题】:Update inside a read uncommitted transaction在读取未提交事务中更新
【发布时间】:2016-08-24 06:08:46
【问题描述】:

我有一个事务隔离级别设置为读取未提交的 SP。 例如

Create Procedure TrailSP
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRY

UPDATE TrialTable
SET TrailColumn ='Update'
WHERE TrailID=1

--this is followed by more updates and selects

END TRY
BEGIN CATCH

RETURN -1;
END CATCH

RETURN 0;

我想知道的是,我在 SP 中给出的第一个更新会在执行时立即提交,还是会在 Sp 结束时与其余逻辑一起提交。

【问题讨论】:

  • 您的程序中是否存在丢失和/或重复数据?将隔离级别设置为未提交读就像为过程中的每个查询添加 nolock 提示。 sqlblogcasts.com/blogs/tonyrogerson/archive/2006/11/10/…
  • 这是我必须用于存储过程的标准格式的一部分。所以,不能删除它
  • 您是说您的每个程序都使用该隔离级别吗?您确实需要阅读该提示并了解其真正含义。这不是一些神奇的“快速”按钮。这意味着您的任何程序都不准确。如果准确性很重要,那么您需要从公司中删除这种做法。

标签: sql sql-server tsql transactions


【解决方案1】:

事务提交时,它将被提交,就像任何事务隔离级别下的任何更新一样。这与存储过程的结束无关

如果对您的过程的调用有一个事务,那么当那个事务提交时就会发生提交。

如果对您的过程的调用没有事务但会话已启用implicit transactions,那么它将在应用程序显式提交时提交。

如果对您的过程的调用没有事务并且会话具有自动提交事务行为(即最常见的情况),则事务将在 UPDATE 语句完成时提交。

为 UPDATE 启用 READ UNCOMMITTED 是无操作的。

【讨论】:

    【解决方案2】:

    -在 READ UNCOMMITTED 中读取的任何数据都是可能因为写入它的事务回滚而消失的数据。

    -也可能看不到已提交的某些行,因为尚未提交且可能永远不会提交的事务将其删除。

    -也有可能因为PageSplit而导致行丢失或重复。

    基本上一切皆有可能,因此永远不应将读取的数据用于计算应写入数据库的任何内容,否则您可能会损坏数据库。

    TLDR:永远不要使用 READ UNCOMMITTED

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-12
      • 1970-01-01
      • 1970-01-01
      • 2018-01-15
      • 1970-01-01
      相关资源
      最近更新 更多