锁定和并发
8.3锁定
Sql Server有几种不同的方式来锁定数据
举例来说
更新锁在更新操作的开头部分获取
读操作获取共享锁,而写操作获取排它锁
两种独立的锁定体系
分类
第一种影响所有完全共享的数据,并提供行级锁、分页锁、表、数据分页、LOB分页以及索引分页级别上的表级锁
第二种SQL server 内部使用,用来处理索引并发控制,管理对于内部数据结构的访问,以及获取数据分页的个别记录,第二种系统采用闩latch,比锁要少耗资源并能提供性能优化
区别
锁保证逻辑一致性
闩保证物理一致性
自旋锁
用户数据的锁定类型
概念
锁的粒度granularity
行
分页
一个索引键
索引键的一个范围
一个扩展
表
锁的所有权scope
会话
事务
游标
锁的模式
分类
共享锁shared lock
当数据被读取时,sql server自动获取共享锁
共享锁可以被一张表、一个分页、一个索引键、或一个单独的行所持有
许多进程可以在同一数据上持有共享锁,但是没有进程可以在已经有一个共享锁存在的情况下,在该数据上获取排它锁
一般地当一个数据被读取完毕之后,共享锁立即释放,但是可以使用查询提示或不同的事务隔离级别改变这种默认行为
排它锁exclusive lock
当数据被插入、修改、或删除以后,sql server 会自动获取数据上的排它锁
一次只能有一个进程持有特定数据资源上的排它锁
如果别的进程已经排他性地锁定住某个进程所要申请的数据资源,那么该进程无法获取任何类型的锁
排它锁会保留到事务结束为止
这就意味着被修改的数据通常在当前事务提交或回滚之前对其他进程来说是不可用的
其他进程可以通过查询提示来读取排他性锁定的数据
更新锁update lock
实际上并不是一种独立的锁,他们是共享锁和排它锁的混合
当sql server执行一个数据修改操作,但首先需要搜索表以寻找到要被修改的资源时,更新锁就会被获取
通过使用查询提示,一个进程可以明确的申请更新锁
提供对其他数据读者的兼容性,在确保数据自上次读取以后尚未修改的前提下,是进程能够在稍后对数据进行修改。
更新锁不足以使用户修改数据,所有的数据修改都要求被修改的资源上存在排它锁
更新锁的作用就好像一个串行化阀门,将后续申请排它锁的请求压入队列中
只要有一个进程对资源持有更新锁,其他进程就无法获取该资源的更新锁或排它锁
而其他正在申请相同资源的更新锁或排它锁就必须等待
持有更新锁的进程可以将其转换为排它锁,因为更新锁避免了与其他进程的锁的兼容性
可以将更新锁看作意图更新intent to update
更新锁一直保留到事务结束,或转化为排他锁
SQL server使用更新锁适用于任何需要在进行实际修改之前搜索数据的数据修改操作
这样的操作包括受限更新和删除
也包括带有聚集索引的表进行插入操作
sql Server必须先搜索数据(使用聚集索引)以找到正确的位置来插入新的记录
当sql server 只进行到搜索阶段时,它会采用更新锁来保护数据,而只有它找到正确的位置并开始插入以后才将更新锁升级为排它锁
意向锁intent lock
特殊锁定方式
架构稳定锁schema stability locks
当查询被编译时,架构稳定锁会防止其他进程获取架构修改锁
架构更改锁schema modification locks
大容量更新锁bulk update locks
当执行bulk insert 或bcp工具将数据导入表时就会获取大容量更新锁
大容量导入操作必须使用tablock查询提示来获取这个特殊的锁
锁的模式决定了一个并发请求的锁是否兼容