锁-学习笔记(三)
常见资源附加的锁
1、数据库锁
数据库锁有共享、更新、排他3种模式。虽然这3种锁会影响用户对数据库中表数据的操作,但这3种锁的产生原因与表的逻辑数据操作都没有关系,与事务也没关系。
共享锁:数据库的所有连接会自动对数据库附加共享锁,以防止在操作过程中删除数据库或离线数据库(offline)。
更新锁:对某些操作,如执行alter database操作使得数据库离线或修改数据库的设置时,为了降低产生死锁的机会,会先对数据库附加更新锁,然后再把更新锁转换为排他锁,转换成功后才能完成alter database操作。alter database语句不能放置于显示事务中执行,必须作为一个事务单独执行,从而对数据库附加排他锁及更新锁的时间一般不会持续过长,对数据库中其他操作的影响一般也很小。
排他锁:当某个数据库操作需要排他使用时,如删除数据库或修改数据库名称时,会对数据库直接附加X锁。
因为master和tempdb数据库不能离线,也不能被删除,所以这两个数据库一般不会加锁。
创建一个数据名称为testLock,并在该数据库中创建 锁-学习笔记(二)中的锁查询视图dbLocks,对testLock数据库启动两个连接(新建两个查询),假设为连接1、连接2。
在连接1中查询当前锁的信息,可以看到这两个连接对数据各自附加了一个共享锁,各个列的含义详见锁-学习笔记(二):
select * from dbLocks
go

在连接2中执行数据库离线命令
alter database testLock set offline
go
重新在连接1查询锁的情况
select * from dbLocks
go

由查询结果的第1行和第4行可以发现,因为更新锁与共享锁兼容,当连接2执行数据库离线操作时,对数据库附加了更新锁,而在更新锁转换为排他锁时,则与连接1附加的共享锁互斥而发生等待。
取消连接2中的操作,然后在连接2中执行下面的命令修改数据库名称:
use master
go
alter database testLock modify name=testLock1
go
连接2中的当前修改数据库名称操作会发生等待。
在连接1中,查询当前锁的情况,可以发现,修改数据库名称直接对其附加了排他锁:
select * from dbLocks
go

如果等待时间过长,连接2中的操作会被取消,并给出以下错误信息:

在连接2中执行删除数据库也会发生等待:
use master
go
drop database testLock
go
在连接1中查询锁的情况,会发现执行删除数据库操作时,对其附加了排他锁:

一段时间后连接2会给出以下错误信息:

对数据库添加文件组或数据文件、修改数据文件大小都不会对数据库附加排他锁,删除文件组或数据文件只取决于文件组或数据文件中是否已经存放了数据,也不会对数据库附加排他锁。
alter database testLock add filegroup testPFS
go
alter database testLock
add file
(
name='testPFS_data',
filename='e:\sqldata\testPFS_data.ndftestLock.ndf'
)
to filegroup testPFS
go


浙公网安备 33010602011771号