标签:兼容 产生 用户 多个 tab 不能 数据 系统 可重复
SqlServer通过普通锁来保护数据库的内容(内容),通过闩锁保护内存的数据结构(缓冲区)。锁冲突会产生等待,在高并发或长作业时会严重影响性能。因此有必要了解锁的相关知识,减少锁冲突。锁模式决定锁的互斥类别,锁粒度决定锁的影响范围,事务隔离级别决定是否在读数据的时候使用锁、读锁的持续时间、读已经被排它锁定资源时的行为(等待锁释放,读没有提交的数据,读最后提交的版本)。在生产环境中你可能会遇到锁升级、闩锁等待时间过长等锁相关问题。
共享锁:不会进行改变内容的操作,其他用户允许读取。
排它锁:不允许其他用户在资源上创建任何形式的新锁。
更新锁:更新锁是共享锁和排他锁的混合。
意向锁:假如你锁定了某一行,那么同时也加了表的意向锁。意向锁可改进性能,因为SqlServer只需要在表层次上检查意向锁,而不需要检查表上的每个行锁或者页锁。防止其他事务以会使较低级别的锁无效的方式修改较高级别资源。 提高数据库引擎在较高的粒度级别检测锁冲突的效率。
架构锁:架构稳定锁用来防止模式修改,架构修改锁防止修改期间
大容量更新锁:大容量更新锁允许进程将数据并发地大容量复制到同一张表,同时防止其它不进行大容量复制数据的进程访问该表。
行、页、区、分区表、表、文件、数据库
Read Committed(已提交读):等待锁释放。读操作完之后立即释放锁。 SqlServer的默认隔离级别。
Read UnCommitted(未提交读):在读数据时不会检查或使用任何锁。
Repeatable Read(可重复读):等待锁释放。保持共享锁直到事务结束。只在读取页的期间内控制共享锁
Serializable(可序列化):不仅会锁定受影响的数据,还会锁定查询锁定的范围。(阻止了新数据插入查询范围)
SnapShot(快照):会读取最后提交的版本,不会被锁定
注:无论定义什么隔离级别,对数据的更改总是通过排他锁来锁定并直到事务结束时才释放。
默认情况每个sql语句都是一个事务。
被GO语句隔开的所有SQL语句会编译成一个执行计划并发送到服务器,与任何其他批处理无关,一个批处理中的错误不会阻止另一个批处理运行。
锁升级非常重要,因为它可以帮助SqlServer节约内存空间。锁升级只是“尝试”进行的,如果存在不兼容性的锁就不会进行升级。在SqlServer里当你请求的行数超过5000(Insert,Update,Delete)就会发生锁升级,产生一个排它表锁。这时默认情况下(非未提交读),所有与该表相关的读操作将被挂起。
对于批量更新操作(Insert,Update,Delete)为了避免锁升级,可以分批去执行语句(每次影响行数<5000)。对于分区表默认是直接升级到表(LOCK_ESCALATION=TABLE),要想升级到分区表需设置表模式为自动(ALTER TABLE [TableName] SET (LOCK_ESCALATION=AUTO))。对于历史分区的分区表锁不会影响最新分区的操作。
闩锁是为了保护内存的数据结构(缓冲区),比如为了防止多个线程同时写一个数据页会在写之前加上闩锁。
SqlServer创建和删除临时表时会有空间的分配和回收,这时会修改数据分配页的标识。高并发环境下频繁修改数据分配页会导致长时间的闩锁阻塞(Buffer Latch),影响并发性能。可以为tempdb指定多个数据文件将分配页的修改压力分摊到多个文件上(文件个数=CPU的核心数)。
闩锁类型:
闩锁模式:
参考
锁类型
http://www.cnblogs.com/kissdodog/p/3170036.html
事务隔离级别
http://www.cnblogs.com/qanholas/archive/2012/01/02/2310164.html
锁升级
http://www.cnblogs.com/woodytu/p/5488602.html
闩锁
http://www.cnblogs.com/Joe-T/p/4826677.html
标签:兼容 产生 用户 多个 tab 不能 数据 系统 可重复
原文地址:http://www.cnblogs.com/ciwen91/p/6245930.html