sql - 为什么 SQL 语句不起作用?交易如何运作?
问题描述
问题表达:
我正在尝试一些关于交易的事情。考虑以下操作:
- 在 SQL Server Management Studio 中打开连接窗口 1
BEGIN
一个事务,然后从表 A 中删除大约 2000 行数据- 在 SQL Server Management Studio 中打开另一个连接窗口 2
- 在窗口 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 用于它们的内存量。
解决方案
您正在经历的是“锁升级”。默认情况下,SQL Server 使用(我认为)行级锁进行删除。但是,如果一个表达式具有超过某个阈值(5,000 个锁),则 SQL Server 会将锁定升级到整个表。
这是一种自动机制,您可以根据需要将其关闭。
在 SQL Server 文档和相关文档中都有很多关于此的信息。
推荐阅读
- node.js - “抛出错误”错误消息不断出现
- java - Java stream().noneMatch(...) 和 !stream().anyMatch(...) 之间的区别
- c# - 如何在 C# 项目的 App_Code 文件夹中一起使用 VB.NET 类
- sql - 使用相关子查询从另一个表中应用列值
- reactjs - 酶发现无法在已经变浅的组件内查找组件
- reactjs - React prod build 中的 Jumbotron 背景图像不呈现
- assembly - 当推入堆栈时,8 字节值以 4 字节块反转,而不是基于每个字节
- asp.net-core - 带有 redis 分布式缓存的 asp.net 核心会话存储
- java - 我应该如何在 Gentics Mesh 中实现带有重复事件的日历?
- javascript - 如何将 Vimeo 视频响应式嵌入到 Slick Slider 中?