简介
SQL Server通过锁,就像十字路口的红绿灯那样,告诉所有并发的连接,在同一时刻上,哪些资源可以读取,哪些资源可以修改。
当一个事务需要访问的资源加了其所不兼容的锁,SQL Server会阻塞当前的事务来达成所谓的隔离性。直到其所请求资源上的锁被释放
如何查看锁
使用sys.dm_tran_locks这个DMV
查询时间点的数据库锁的情况,并不包含任何历史锁的记录
锁的粒度
锁是加在数据库对象上的。而数据库对象是有粒度的,比如同样是1这个单位,1行,1页,1个B树,1张表所含的数据完全不是一个粒度的。因此,所谓锁的粒度,是锁所在资源的粒度
锁的粒度和锁的类型都是由SQL Server进行控制的
锁会给数据库带来阻塞,因此越大粒度的锁造成更多的阻塞,但由于大粒度的锁需要更少的锁,因此会提升性能。而小粒度的锁由于锁定更少资源,会减少阻塞,因此提高了并发,但同时大量的锁也会造成性能的下降
锁的升级
实际上,每个锁会占96字节的内存,如果有大量的小粒度锁,则会占据大量的内存,直到内存达到下一级别的锁容量,会自动升级成下个级别的锁
例:当我们选择300行数据时(表数据总共3W行),SQL Server会加对应行数的Key锁,共300个key锁。但是当我们需要查询6K行数据时, 此时如果用6000个键锁的话,则会占用大约96*6000=600K左右的内存, 所以为了平衡性能与并发之间的关系,SQL Server使用一个表锁来替代6000个key锁,这就是所谓的锁升级
锁模式
理解死锁
可以看到,出现死锁后,SQL Server并不会袖手旁观让这两个进程无限等待下去,而是选择一个更加容易Rollback的事务作为牺牲品,而另一个事务得以正常执行