Entity Framework与SQL Server锁相关:saveChanges()锁表还是锁行?
问题解答
关于Entity Framework中SaveChanges()的锁粒度
SaveChanges()本身不直接控制锁的粒度,锁是由底层SQL Server引擎决定的:
- EF默认会为单次
SaveChanges()的所有变更操作隐式开启一个事务,所有操作执行完成后自动提交事务。 - 正常情况下,单次提交的变更行数少、未触发SQL Server锁升级阈值时,只会锁定涉及的对应数据行,不会锁整个表。
- 如果单次
SaveChanges()提交的变更行数过多(SQL Server默认锁升级阈值为5000行),会触发锁升级,将大量行锁合并为表锁,此时相关表会被整体锁定直到事务结束。
关于无显式事务时普通UPDATE查询的加锁逻辑
就算你没有手动开启事务,SQL Server的单条UPDATE语句也一定会执行加锁操作:
- SQL Server默认开启隐式事务模式,单条DML语句执行时会自动开启事务,语句执行完成后自动提交释放锁,所以不会出现无锁的UPDATE操作。
- 普通UPDATE默认优先加行级排他(X)锁,只有两种情况会升级为表锁:一是UPDATE的过滤条件没有命中索引,导致全表扫描,SQL Server会直接加表级锁;二是UPDATE涉及的行数过多触发锁升级。
- 日常操作中感知不到无事务UPDATE的锁,是因为单条语句执行速度快,锁持有时间极短,几乎不会造成阻塞。
内容的提问来源于stack exchange,提问作者StackStaNw
相关产品推荐
相关产品推荐

