You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何事务未被锁定?同一资源未提交/回滚时第二个事务未阻塞的技术咨询

为什么第二个事务没有被阻塞?

你的问题核心其实和SQL Server对事务的处理逻辑以及锁机制的工作方式有关,咱们一步一步拆解:

1. SQL Server的"嵌套事务"并不是真的独立事务

你写的两个BEGIN TRANSACTION看起来像是开启了两个独立事务,但实际上SQL Server里没有真正的嵌套事务——它只会维护一个事务计数(@@TRANCOUNT):

  • 第一个BEGIN TRANSACTION会把@@TRANCOUNT从0改成1
  • 第二个BEGIN TRANSACTION只是把计数再加1(变成2),并没有创建一个全新的、独立的事务上下文

只有当你执行COMMIT TRANSACTION把@@TRANCOUNT降到0的时候,才会真正提交整个事务。所以你最后那个COMMIT只是把计数从2减到1,整个会话仍然处于未提交的事务状态,从头到尾只有一个实际的事务在运行。

2. 同一个会话内的锁不会自我阻塞

数据库的锁机制是用来解决不同会话之间的并发冲突问题的。当你在同一个会话里执行操作时,后续的更新会直接复用当前会话已经持有的锁,不会被自己持有的锁阻塞:

  • 第一个UPDATE已经获取了DirectionID=1这行数据的排他锁(X锁)
  • 同一个会话里的第二个UPDATE操作请求的是同一行的锁,数据库会直接允许这个操作,因为它知道这是同一个会话的请求,不会产生冲突

如果是两个不同的会话分别执行这两段SQL,那第二个会话的UPDATE就会被阻塞,直到第一个会话提交或回滚释放锁。你可以自己验证:打开两个数据库客户端窗口,第一个窗口执行第一段BEGIN TRANSACTION; UPDATE ...,第二个窗口执行第二段BEGIN TRANSACTION; UPDATE ...,这时第二个窗口就会卡住,直到第一个窗口执行COMMIT或ROLLBACK。


内容的提问来源于stack exchange,提问作者user20291246

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 13:02:46