【发布时间】: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