SQLServer 默认隔离级别:Read Committed
先看执行结果:
试验1:
图1: 查询Production表(几千万条数据)
图2: 在图1执行的时候更新无阻塞
试验2:
SQLServer 修改Session Level隔离级别: REPEATABLE Read
图3: 查询产量表(千万级)
图4: 在图3查询产量的时候更新产量表阻塞
结论如下:
在 Read Committed(不使用row-versioning) 隔离级别下,在读操作执行时,申请和持有Share Lock;一旦读操作完成,释放Shared Lock;
在 Repeatable Read 和 Serializable隔离级别下,事务会持有Shared Lock,直到事务结束(提交或回滚);
这里本人有个疑问:产量表千万级查询的时候共享锁,为何还能更新呢?
我们应当学会透过现象看本质 试验3:看下 试验1 查询产量表的时候数据库如何增加锁的?
图5: 先获取seession_id
然后让图5的语句再执行一遍。
图6:在上面的SQL执行过程钟执行如下查看加锁语句,可以看到Page页锁
图7:再执行一次,可以看到Page页锁发生变化了。
试验4:看下 试验2 查询产量表的时候数据库如何增加锁的?
图8:Repeatable Read隔离级别,先查询Session_ID
图9: 在上面的SQL执行过程钟执行如下查看加锁语句,可以看到2164个页锁
图10:过几秒钟,再执行一次,可以看到41个表锁,(看来页锁过多的时候SQLServer会自动上升升级为表锁)
由此可以看出,默认隔离级别:查询与更新无阻塞,Page页锁申请和持有,一旦读取完毕,会立即释放,不会一直持有。 Repeatable隔离级别:查询与更新阻塞,Page页锁申请和持有,直到整个事务执行完毕,才会释放页锁,由此页锁一直持有升级为表锁。
欢迎大佬们指点纠正。(谢谢大佬指正,本人已修正)