症状
假设在 Microsoft SQL Server 中使用 WITH DTC_SUPPORT = PER_DB 子句创建可用性组。 尝试在事务或系统存储过程(例如sp_executesql)中执行 SAVE TRANSACTION 语句时,会收到以下错误消息之一:
Msg 627,级别 16,状态 0, LineNumber
不能在分布式事务中使用 SAVE TRANSACTION。
Msg 12324,级别 16,状态 100, LineNumber
内存优化表不支持分布式事务 (DTC) 。
错误: 3933, 严重性: 16, 状态: 1.
无法将事务升级到分布式事务,因为此事务中有一个活动保存点。
原因
为 WITH DTC_SUPPORT = PER_DB 启用 Always On 可用性组中的数据库时,只要事务涉及多个数据库,事务在 2016 SQL SERVER SP2 和 2017 SQL Server升级到 MSDTC 事务。 MSDTC 事务存在限制,例如无法使用保存点,无法使用内存优化表。
在某些情况下,跨数据库事务发生的不是因为用户有涉及两个用户数据库的事务,而是因为事务涉及当前数据库和系统数据库 (master、tempdb、model、system resource database) 。 由于系统资源数据库实际上是只读的,因此,如果跨数据库事务涉及系统资源数据库而非其他系统数据库,则无需升级到 MSDTC 事务。
解决方法
如果在同一SQL Server实例中涉及跨数据库事务,则此 KB 中引入的修补程序将跳过对 MSDTC 事务的升级,因为系统资源数据库和已启用PER_DB DTC 的可用性组的用户数据库都涉及到跨数据库事务。
因此,如果上面列出的错误的原始原因是涉及系统资源数据库的跨数据库事务,则此修补程序将解决此问题。 有时,用户可能会看到上面列出的错误,其根本原因相同。 下面列出了应用此修补程序的条件:
-
数据库是启用了 WITH DTC_SUPPORT = PER_DB 的Always On可用性组的一部分。
-
跨数据库事务涉及同一SQL Server实例中的此数据库和系统资源数据库。
-
在跨数据库事务中,使用 SAVE TRANSACTION,或涉及内存优化表。
如果没有此修补程序,此类事务将失败,出现上面列出的错误。 通过此修复,此类事务应继续进行。
注意:此修补程序解决了涉及系统资源数据库的跨数据库事务,但涉及用户数据库并包含 SAVE TRANSACTION 语句的任何跨数据库事务仍将失败,必须重写。
以下SQL Server累积更新中修复了此问题:
SQL Server的每个新的累积更新都包含上一个累积更新中包含的所有修补程序和所有安全修补程序。 查看SQL Server的最新累积更新:
更多信息
有关 DTC_SUPPORT = PER_DB、内存优化表、 SAVE TRANSACTION 的其他信息,可在以下链接中找到。
同一SQL Server实例中的数据库事务将此部分链接到 https://learn.microsoft.com/en-us/sql/database-engine/availability-groups/windows/transactions-always-on-availability-and-database-mirroring?view=sql-server-2017#sql-server-2016-sp1-and-before-support-for-cross-database-transactions-within-the-same-sql-server-instance
内存优化表将此部分链接到
https://learn.microsoft.com/en-us/sql/relational-databases/in-memory-oltp/transactions-with-memory-optimized-tables?view=sql-server-2017#limitationsSAVE TRANSACTION 将此部分链接到 https://learn.microsoft.com/en-us/sql/t-sql/language-elements/save-transaction-transact-sql?view=sql-server-2017#remarks
状态
Microsoft 已确认这是在“适用范围”部分中列出的 Microsoft 产品存在的问题。
参考
了解 Microsoft 用于描述软件更新的 术语 。