首页 > 解决方案 > 为什么 SQL 语句不起作用?交易如何运作?

问题描述

问题表达:

我正在尝试一些关于交易的事情。考虑以下操作:

  1. 在 SQL Server Management Studio 中打开连接窗口 1
  2. BEGIN一个事务,然后从表 A 中删除大约 2000 行数据
  3. 在 SQL Server Management Studio 中打开另一个连接窗口 2
  4. 在窗口 2 中向表 A 中插入一行新数据(无事务),现在运行成功

然后,我重复相同的操作,但在 STEP 2 中我删除了 10k 行数据,在这种情况下,STEP 4 无法成功运行。我已经等了半个小时了。

它表明它正在执行 SQL...无法完成。最后,我使用连接窗口 1 插入数据,它现在可以工作了。

为什么它适用于 2k 行而不适用于 10k 行?


我执行的Sql语句:

在连接窗口 A 中,我执行 BEGIN TRAN Delete from tableA(10K 行)

在连接窗口 B 中,我执行 Insert into tableA(..) VALUES (...)

windows B 无法成功执行。


非常感谢@Gordon

原因

我搜索关于锁升级的关键字。我尝试使用 SQL Server Profiler 跟踪锁升级,当我删除事务中的许多数据(我不提交或回滚)时,我得到一个锁:升级。

所以,我知道锁升级的概念。我删除了表中的太多数据,然后行锁升级到表升级。我没有提交或回滚它们,其他连接(或应用程序)无法访问带有表锁的表。 在 sql profiler 中跟踪锁升级


当 MSSQL Server 中发生锁升级时

"locks 选项也会影响何时发生锁升级。当 locks 设置为 0 时,当当前锁结构使用的内存达到数据库引擎内存池的 40% 时,会发生锁升级。当 locks 未设置为 0 时,锁升级当锁的数量达到为锁指定的值的 40% 时发生。"


如何设置使用 SQL Server Management Studio 会影响锁升级:

配置锁定选项 在对象资源管理器中,右键单击服务器并选择属性。

单击高级节点。

在 Parallelism 下,为 locks 选项键入所需的值。

使用 locks 选项设置可用锁的最大数量,例如限制 SQL Server 用于它们的内存量。

标签: sqlsql-servertransactionslocking

解决方案


您正在经历的是“锁升级”。默认情况下,SQL Server 使用(我认为)行级锁进行删除。但是,如果一个表达式具有超过某个阈值(5,000 个锁),则 SQL Server 会将锁定升级到整个表。

这是一种自动机制,您可以根据需要将其关闭。

在 SQL Server 文档和相关文档中都有很多关于此的信息。


推荐阅读