REPEATABLE READ隔离级别是否会对调用存储过程内的读操作加读锁?
结论
这个问题要根据内层存储过程CheckIfDataIsOk是否显式设置了独立的事务隔离级别分两种情况判断,核心规则是:SQL Server中存储过程内部显式声明的事务隔离级别,会在存储过程执行期间临时覆盖外层的隔离级别配置,存储过程执行完成后会自动恢复外层的隔离级别。
情况1:内层存储过程显式设置了READ UNCOMMITTED
你给出的示例中内层存储过程第一行就声明了SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED,那么执行EXECUTE [dbo].[CheckIfDataIsOk]读取数据时:
- 读操作遵循
READ UNCOMMITTED的规则,不会加共享读锁,允许脏读,完全不会触发外层REPEATABLE READ的锁机制 - 哪怕外层已经开启了事务,内层的读操作也不会持有共享锁到事务结束
情况2:内层存储过程未自定义隔离级别,或显式设置为READ COMMITTED
如果内层没有显式修改隔离级别,会继承外层的REPEATABLE READ配置,执行读操作时就会加共享锁,并且锁会一直持有到整个外层事务提交/回滚,符合可重复读的隔离特性。
如果内层显式设置为READ COMMITTED,则读操作的共享锁会在数据读取完成后立即释放,不会持有到事务结束,也不会触发外层REPEATABLE READ的锁行为。
额外说明
外层存储过程自身后续直接操作目标行数据时,会使用外层声明的REPEATABLE READ隔离级别,对应的读/写锁都会持有到事务结束。
另外要注意你示例中内层存储过程写了BEGIN TRANSACTION/COMMIT,在已经开启外层事务的场景下,内层的事务操作只会增减事务计数@@TRANCOUNT,不会真正开启独立事务,也不会提前提交数据,最终的事务提交还是由外层的COMMIT触发。
内容的提问来源于stack exchange,提问作者lezebulon
相关产品推荐
相关产品推荐

