假设某个用户(假设为A)发出如下的语句更新一条记录:
SQL> update employees set last_name='HanSijie'
where employee_id=100;
上面的例子,这时A用户已经发出了更新employee_id为100的记录的SQL语句。当A还没有提交之前,另外一个用户D发出下面的语句:
SQL> drop table employees;
由于用户A还没有提交所做的事务,因此该事务还没有结束,其他用户还不能删除该表,否则A所发出的事务就无法正常结束。为了阻止这时用户D的删除操作,我们能够想到的最直观的方法就是,在执行删除表的命令之前,先依次检查employees表里的每一条记录,查看每一条数据行的头部是否存在锁定标记,如果是,则说明当前正有事务在更新该表,删除表的操作必须等待。
显然,这种方式会引起很大的性能问题,Oracle不会采用这种方式。实际上,当我们在对employees表的数据进行更新时,不仅会在数据行的头部记录行级锁,而且还会在表的级别上添加一个表级锁。那么当D用户要删除表时,发现employees表上具有一个表级锁,于是等待。
通过这种在表级别上添加锁定的方式,我们就能够比较容易并且高效地(因为不需要扫描表里的每一条记录来判断在表上是否有DML事务)对锁定进行管理了。表级锁共具有五种模式,如下所示。
行级排他锁(Row Exclusive,简称RX锁)
当我们进行DML时会自动在被更新的表上添加RX锁,或者也可以通过执行lock命令显式的在表上添加RX锁。在该锁定模式下,允许其他的事务通过DML语句修改相同表里的其他数据行,或通过lock命令对相同表添加RX锁定,但是不允许其他事务对相同的表添加排他锁(X锁)。
行级共享锁(Row Shared,简称RS锁)
通常是通过select … from for update语句添加的,同时该方法也是我们用来手工锁定某些记录的主要方法。比如,当我们在查询某些记录的过程中,不希望其他用户对查询的记录进行更新操作,则可以发出这样的语句。当数据使用完毕以后,直接发出rollback命令将锁定解除。当表上添加了RS锁定以后,不允许其他事务对相同的表添加排他锁,但是允许其他的事务通过DML语句或lock命令锁定相同表里的其他数据行。
共享锁(Share,简称S锁)
通过lock table in share mode命令添加该S锁。在该锁定模式下,不允许任何用户更新表。但是允许其他用户发出select …from for update命令对表添加RS锁。
排他锁(Exclusive,简称X锁)
通过lock table in exclusive mode命令添加X锁。在该锁定模式下,其他用户不能对表进行任何的DML和DDL操作,该表上只能进行查询。
共享行级排他锁(Share Row Exclusive,简称SRX锁)
通过lock table in share row exclusive mode命令添加SRX锁。该锁定模式比行级排他锁和共享锁的级别都要高,这时不能对相同的表进行DML操作,也不能添加共享锁。
这五种模式的TM锁的兼容关系如下表所示(√表示互相兼容的请求;×表示互相不兼容的请求;N/A表示没有锁定请求):
- |
S |
X |
RS |
RX |
SRX |
N/A |
S |
√ |
× |
√ |
× |
× |
√ |
X |
× |
× |
× |
× |
× |
√ |
RS |
√ |
× |
√ |
√ |
√ |
√ |
RX |
× |
× |
√ |
√ |
× |
√ |
SRX |
× |
× |
√ |
× |
× |
√ |
N/A |
√ |
√ |
√ |
√ |
√ |
√ |
从前面的描述中可以看到,我们不仅可以通过发出DML语句的方式,由Oracle自动在表级别上添加TM锁。我们还可以通过发出lock table命令主动地在表级别上添加TM锁,并在该命令中可以指定不同的锁定模式,其命令格式如下所示:
lock table in [row share][row exclusive]
[share][share row exclusive][exclusive] mode;
对Oracle数据库中的各SQL语句所产生的表级锁的情况进行汇总,如下表所示:
SQL语句 |
表锁定模 |
允许的表锁定模式 |
Select * from …… |
RS |
RS、RX、S、SRX、X |
Insert into …… |
RX |
RS、RX |
Update …… |
RX |
RS、RX |
Delete from …… |
RX |
RS、RX |
Select * from for update |
RS |
RS、RX、S、SRX |
lock table in row share mode |
RS |
RS、RX、S、SRX |
lock table in row exclusive mode |
RX |
RS、RX |
lock table in share mode |
S |
RS、S |
lock table in share row exclusive mode |
SRX |
RS |
lock table in exclusive mode |
X |
RS |
对于通过lock table命令主动添加的锁定来说,如果要释放它们,只需要发出rollback命令即可。
总机:(010)-56426307,59426319 QQ讨论群:243729577 182441349 邮箱:yuezt@cuug.com
通信地址:北京市海淀区紫竹院路88号紫竹花园D座703(CUUG)邮政编码:100089
中国UNIX用户协会 Copyright 2010 ALL Rights Reserved 北京神脑资讯技术有限公司
京ICP备11008061号