【问题标题】:SQL Server in-memory oltp transaction snapshot isolationSQL Server 内存中 oltp 事务快照隔离
【发布时间】:2019-03-03 10:59:09
【问题描述】:

试图了解事务隔离级别如何在 SQL Server 内存优化表(内存中 oltp)上发挥作用。

如果我执行以下查询:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRANSACTION

SELECT *
FROM tm.Tasks

显示错误消息:

仅自动提交事务支持使用 READ COMMITTED 隔离级别访问内存优化表。显式或隐式事务不支持它。使用表提示(例如 WITH (SNAPSHOT))为内存优化表提供支持的隔离级别。

现在,如果我通过添加表提示来修改查询,它可以工作:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO

BEGIN TRANSACTION

SELECT *
FROM tm.Tasks WITH(SNAPSHOT)

但如果我通过SET TRANSACTION ISOLATION LEVEL SNAPSHOT 更改事务隔离级别并删除表提示:

SET TRANSACTION ISOLATION LEVEL SNAPSHOT

BEGIN TRANSACTION

SELECT *
FROM tm.Tasks

它再次显示错误消息不起作用:

当会话 TRANSACTION ISOLATION LEVEL 设置为 SNAPSHOT 时,无法访问或创建内存优化表和本机编译模块。

为什么它与表提示一起使用,并通过设置事务隔离级别

SET TRANSACTION ISOLATION LEVEL SNAPSHOT

没有?

更新:尝试将MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT 设置为ON,仍然从上次查询中得到相同的错误:

当会话 TRANSACTION ISOLATION LEVEL 设置为 SNAPSHOT 时,无法访问或创建内存优化表和本机编译模块。

【问题讨论】:

  • 你需要使用MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT,除了明确使用SET TRANSACTION ISOLATION LEVEL SNAPSHOT。换句话说,将SET TRANSACTION ISOLATION LEVEL READ COMMITTED 与此选项结合使用(和/或READ_COMMITTED_SNAPSHOT,如果您希望对基于磁盘的对象使用相同的选项)。诚然,这有点令人困惑,但当您同时处理基于磁盘和内存对象的事务时,这会更有意义。
  • @JeroenMostert 据我所知,READ_COMMITTED_SNAPSHOT(悲观写入)与 SNAPSHOT(乐观写入)不同。因此,如果我需要同时涉及磁盘和内存优化表的事务,是否无法使用 SNAPSHOT 隔离级别?
  • READ_COMMITTED_SNAPSHOT 仅表示READ COMMITTED 被视为SNAPSHOT。乐观与悲观没有区别;快照隔离始终是乐观的,因为如果在事务启动后修改了数据,则写入将失败。如果您想要基于锁的READ COMMITTED 语义(“悲观”)并具有有效的快照隔离,您可以使用READCOMMITTEDLOCK 表提示。结合内存和磁盘表的显式事务有点棘手,但它们应该不是很常见。

标签: sql-server sql-server-2016 memory-optimized-tables snapshot-isolation in-memory-oltp


【解决方案1】:

如果您真的想了解在引用传统和内存优化表时内存中 OLTP 支持的隔离级别,您还必须了解事务启动模式。

所有这些都在我的帖子中进行了详细说明:

http://nedotter.com/archive/2017/08/all-about-in-memory-isolation-levels-part-1/ http://nedotter.com/archive/2017/08/all-about-in-memory-isolation-levels-part-2/

如果您对这个经常被误解的话题还有其他问题,请告诉我。

【讨论】:

    【解决方案2】:

    MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT 数据库选项必须打开才能使用不带提示的显式SNAPSHOT 事务。下面是excerpt from the documentation(强调我的):

    显式 - 您的 Transact-SQL 包含代码 BEGIN TRANSACTION, 以及最终的 COMMIT TRANSACTION。两个或多个语句可以 被归入同一事务。 在显式模式下,您必须 使用数据库选项 MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT 或 编写有关事务隔离级别的表提示 FROM 子句中的内存优化表。

    以下是显示如何打开此数据库选项的示例:

    ALTER DATABASE YourDatabase
        SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT = ON;
    

    【讨论】:

      猜你喜欢
      • 2010-11-10
      • 2014-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多