- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有下表:
CREATE TABLE [dbo].[table1](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](50) NULL,
CONSTRAINT [PK_table1] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
我正在学习 SQL 锁的工作原理,并且我正在尝试测试一种情况,在这种情况下我想锁定一行以防止读取和更新。此任务中的一些灵感来自此 article , 这是 original problem我正在尝试解决。
当我运行此 T-SQL 时:
BEGIN TRANSACTION
SELECT * FROM dbo.table1 WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:15'
COMMIT TRANSACTION
我希望在表上放置一个独占锁,特别是针对行(如果我在主键上有一个 WHERE 语句)
但是运行这个查询,我可以看到 GRANTed LOCK 是针对请求模式 IX。
SELECT * FROM sys.dm_tran_locks WHERE resource_database_id = DB_ID() AND resource_associated_entity_id = OBJECT_ID(N'dbo.table1');
此外,在单独的 SSMS 窗口中,我可以在事务运行时完全查询表。
为什么 MSSQL 不遵守锁定提示?
(SQL 服务器 2016)
编辑 1
任何有关这些锁如何工作的信息都值得赞赏,但是,手头的问题是 SQL Server 似乎没有强制执行我指定的锁。我的直觉是,这与行版本控制或相关内容有关。
编辑2
我创建了这个 Github gist .它需要 .NET 和外部库 Dapper 才能运行(可通过 Nuget 包获得)。
这是我注意到的有趣的事情:
table1
运行,即使先前使用 UPDLOCK, HOLDLOCK
的查询已被请求。这是该 Gist 的控制台输出:
Run locking SELECT Start - 00:00:00.0165118
Run NON-locking SELECT Start - 00:00:02.0155787
Run NON-locking SELECT Finished - 00:00:02.0222536
Run INSERT Start - 00:00:04.0156334
Run UPDATE ALL Start - 00:00:06.0259382
Run UPDATE EXISTING Start - 00:00:08.0216868
Run UPDATE NON-EXISTING Start - 00:00:10.0236223
Run UPDATE NON-EXISTING Finished - 00:00:10.0268826
Run locking SELECT Finished - 00:00:31.3204120
Run INSERT Finished - 00:00:31.3209670
Run UPDATE ALL Finished - 00:00:31.3213625
Run UPDATE EXISTING Finished - 00:00:31.3219371
最佳答案
and I'm trying to test a situation where I want to lock a row from being read and updated
如果你想锁定一行不被读取和更新,你需要一个独占锁,但是UPDLOCK
锁提示请求更新锁,而不是独占锁。查询应该是:
SELECT * FROM table1 WITH (XLOCK, HOLDLOCK, ROWLOCK)
WHERE Id = <some id>
此外,在 READ COMMITTED SNAPSHOT
下和 SNAPSHOT
隔离级别,SELECT
语句不请求共享锁,只请求模式稳定性锁。因此,SELECT
尽管存在独占锁,语句仍可以读取该行。令人惊讶的是,在 READ COMMITTED 隔离级别下,SELECT 语句可能不会请求行级共享锁。您需要向 SELECT
添加查询提示防止它读取锁定行的语句:
SELECT * FROM dbo.Table1 WITH (REPEATABLEREAD)
WHERE id = <some id>
与 REPEATABLEREAD
锁定提示,SELECT
语句将请求共享锁并在事务期间持有它们,因此它不会读取独占锁定的行。请注意,使用 READCOMMITTEDLOCK
这还不够,因为 SQL Server 在某些情况下可能不会请求共享锁,如 this 中所述博文。
在默认隔离级别下READ COMMITTED
,并且没有锁定提示,SELECT
statements 为其读取的每一行请求共享锁,并且这些锁在读取该行后立即释放。但是,如果您使用 WITH (HOLDLOCK)
,共享锁一直持有到事务结束。考虑到锁兼容性表,SELECT
在 READ COMMITTED
下运行的语句, 可以读取任何未被独占锁定的行(IX、SIX、X 锁)。 INSERT
请求独占锁, UPDATE
和 DELETE
声明或 SELECT
带有 XLOCK
的语句提示。
I would expect an exclusive lock to be placed on the table, and specifically for the row (if I had a WHERE statement on the primary key)
I need to understand WHY SQL Server is not respcting the locking directives given to it. (i.e. Why is an exclusive lock not on the table, or row for that matter?)
UPDLOCK
hint 不请求独占锁,它请求更新锁。此外,可以在行本身以外的其他资源上授予锁,可以在表、数据页、索引页和索引键上授予锁。 SQL Server 可以锁定的资源类型的完整列表是:DATABASE, FILE, OBJECT, PAGE, KEY, EXTENT, RID, APPLICATION, METADATA, HOBT, and ALLOCATION_UNIT
.当ROWLOCK
如果指定了提示,SQL Server 将锁定行,而不是页、范围或表,SQL Server 将锁定的实际资源是 RID
的和KEY
的
关于sql-server - UPDLOCK 和 HOLDLOCK 查询未创建预期的锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49679269/
我对java有点陌生,所以如果我犯了一个简单的错误,请原谅我,但我不确定我哪里出错了,我收到的错误是“预期的.class,预期的标识符,而不是声明, ';'预期的。”我尝试了不同的方法,并从这些方法中
This question already has answers here: chai test array equality doesn't work as expected (3个答案) 3年前
我正在学习 Java(对不起,我的英语很差,这不是我的母语),当我在 Eclipse (JavaSE-1.7) 中在我输入的每个“try”中执行“try-finally” block 时,会出现以下消
我收到两个错误,指出 token 上的语法错误,ConstructorHeaderName expected instead & token “(”上的语法错误,< expected 在线: mTM.
我找不到错误。 Eclipse 给我这个错误。每个 { } 都是匹配的。请帮忙。 Multiple markers at this line - Syntax error on token “)”,
代码: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class DoubleIt extends
我正在用 python(Vs 代码)编写代码,但出现此错误: Expected ")" Pylance 错误发生在:def main() 我试着运行我的 main 并将它打印到我的屏幕上。我用谷歌搜
我正在尝试按照 documentation 中的建议使用异步函数。但我收到此错误 意外的 token ,预期 ( async function getMoviesFromApi() { try
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
第一行包含一个表示数组长度的整数p。第二行包含用空格分隔的整数,这些整数描述数组中的每个元素。第三行打印一个整数,指示负数组的数量。 package asgn3; import java.util.*
好的,我是初学者,我必须修复此 java 表达式语言代码才能在我的系统 (Windchill) 中工作,但看起来我在语法中遗漏了一些内容: LWCNormalizedObject lwc =
我无法编译我的程序! 我想我缺少一个花括号,但我怎么也看不出在哪里! import javax.swing.*; import java.awt.*;
我的 jQuery 代码有问题,我的 Firebug 向我发出警告:需要选择器。 这是代码: $("img[id$='_tick']").each(function() { $(this).c
我的新类(class) Fountainofyouth 遇到了问题。尝试构建整个项目后,调试器显示 warning: extended initializer lists only available
我已经从 Java 转向 CPP,并且正在努力围绕构造构造函数链进行思考,我认为这是我的问题的根源。 我的头文件如下: public: GuidedTour(); GuidedTour(string
鉴于以下 for(var i=0; i< data.cats.length; i++) list += buildCategories(data.cats[i]); jsLint 告诉我 Expect
我有这个 json,但 Visual Studio Code 在标题中给了我警告。 [ { "title": "Book A", "imageUrl": "https:
我正在尝试编写一个有条件地禁用四个特殊成员函数(复制构造、移动构造、复制赋值和移动赋值)的包装类,下面是我用于测试目的的快速草稿: enum class special_member : uint8_
所以我用 F# 编写了一个非常简单的程序,它应该对 1000 以下的所有 3 和 5 的倍数求和: [1..999] |> List.filter (fun x -> x % 3 = 0 || x %
我是一名优秀的程序员,十分优秀!