SQL Server 【提高】 锁
数据库并发会带来哪些问题
-
脏读:一个事务读取的记录是另一个未完成事务的一部分
-
不可重复读:一个事务中两次读取记录,而另一个事务在这期间改变了数据,就会发生非重复性读取
-
幻读:在UPDATE的过程中,恰好INSERT了一个全新的数据
-
丢失更新:一个更新成功写入数据库后,而又意外地被另一个事务重写
锁的种类
-
共享(S):用于不更改或不更新数据的读取操作,如 SELECT 语句
-
排他/独占(X):用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。 确保不会同时对同一资源进行多重更新
-
更新锁(U):更新锁允许其他事务在更新之前读取资源。但不可以修改。当给资源A加上更新锁后,代表该资源将在稍后更新,更新锁与共享锁兼容。更新锁会阻塞其他的更新锁和排他锁。因此相同资源上不能存在多个更新锁。在找到需要更新的数据时,更新锁直接转为排他锁,开始更新数据
-
意向锁(I):SQL Server锁定一个粒度比较低的资源时,会在其父资源上加上意向锁,告诉其他查询这个资源的某一部分已经上锁。比如,当我们更新一个表中的某一行时,其所在的页和表都会获得意向排他锁
锁的粒度
- RID 行标识符:用于单独锁定表中的一行
- 键:索引中的行锁,用于保护可串行事务中的键范围
- 页:8 千字节 (KB) 的数据页或索引页
- 扩展盘区:相邻的八个数据页或索引页构成的一组
- 表:包括所有数据和索引在内的整个表
- DB数据库
With(LOCK)
- NOLOCK:只用于SEELCTT,除了本身不锁表(不加任何锁),也不会受其他的已存在的锁影响, 锁住的行数据也照样读
- ROWLOCK:可以用在SELECT, UPDATE和DELETE语句中,在用户取得被更新的行,到该行进行更新,这段时间内不被其它用户所修改
- PAGLOCK:共享页锁,Sql Server默认选项
- UPDLOCK:在读取数据时使用修改锁来代替共享锁,并将此锁保持至整个事务或命令结束。使用此选项能够保证多个进程能同时读取数据但只有该进程能修改数据
- HOLDLOCK:持有共享锁,直到整个事务完成,应该在被锁对象不需要时立即释放,相当于SERIALIZABLE事务隔离级别
- TABLOCK:在整个表上置共享锁直至该命令结束,保证其他进程只能读取而不能修改数据
- TABLOCKX(排它表锁):在整个表上置排它锁直至该命令或事务结束。这将防止其他进程读取或修改表中的数据