据库级别锁定
Oracle可以在数据库、表、行这3个级别上使用锁。
锁定数据库有2种方法:将数据库设置成受限方式、将数据库更改成只读方式。
在shutdown数据库后,通过startup restrict命令来在启动数据库时将其设置成受限方式。也可以通过alter system enable restricted session或alter system disable restricted session语句来在打开数据库的情况下启用或禁用数据库的受限方式。当数据库处于受限方式时,只允许具有 restrictive session系统权限的用户(如sys用户)连接到数据库。已经连接的会话不受alter system enable restricted session语句的影响,只有试图进行连接的新的会话会被限制。
将数据库更改成read only(只读)方式后,只能查询数据而不允许对数据进行任何DML操作。
SQL> STARTUP MOUNT
SQL> ALTER DATABASE OPEN READ ONLY;
如果要将数据库再按读写方式打开,可以用STARTUP FORCE命令重启数据库。
set transaction read only语句可以将事务设置成只读事务,即将数据库"冻结"到该事务开始的那一点上,直至显式地发布了COMMIT或ROLLBACK命令或隐式提交(执行DDL)。在只读事务中所查询到的数据反映的是该事务开始时已经存在的数据库中的数据,即便在此同时其他事务更改并提交了数据库中的数据也是如此,但并不锁定数据库。
(e)表级锁定和行级锁定
在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。
当发布一个insert、update、 delete、select......for update语句时都会自动在被操作的表上加表级别的锁(即TM类型的锁)。也可以用Lock Table语句专门设置一个表级别的锁。表级别的锁被用于在操作表中数据期间(还没提交或回退事务),防止其他用户对表的结构进行更改。
Lock Table语句的语法是:LOCK TABLE [schema.]table_name IN lock_mode MODE [NOWAIT];
lock_mode表示锁的模式,取值是SHARE、ROW SHARE、ROW EXCLUSIVE、SHARE ROW EXCLUSIVE、EXCLUSIVE;
当发布一个insert、update、 delete、select......for update语句时都会自动在被操作的行上加行级别的锁(即TX类型的锁)。行级别的锁被用于在操作表中数据期间(还没提交或回退事务),防止其他用户对正在操作的行的数据进行更改。
当Oracle 执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。要想获得某个表上的TX锁,事务必须首先获得该表上的TM锁。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可。TM锁包括了SS、SX、S、SSX、X 等多种模式,在数据行上只有X锁(排他锁)。
在Oracle中,查询(不带for update子句的select语句)语句不会锁定数据。即使一个事务已经锁定了几行记录或整个表,查询总是不需要为加锁而等待的。Oracle的查询是通过使用在撤销表空间中所存储的、数据被锁定之前的前映像,来不需要等待地、成功地执行的。这种读取前映像的方法提高了数据的并发度,还保证了事务不会读取到脏数据。
Select...For Update语句所加的锁与update语句所加的锁相同:一个行级别的EXCLUSIVE锁、一个表级别的ROW EXCLUSIVE锁。
Select...for update of column_list, 在多表连接锁定时,可以指定要锁定的是哪几张表,而如果表中的列没有在for update of 后面出现的话,就意味着这张表其实并没有被锁定,其他用户是可以对这些表的数据进行update操作的。这种情况经常会出现在用户对带有连接查询的视图进行操作场景下。用户只锁定相关表的数据,其他用户仍然可以对视图中其他原始表的数据来进行操作。
在Oracle中,锁的数量不受限制且不会自动升级。(有些数据库中,某个表上的行级锁达到一定数量后,这些行级锁就会被升级为该表上的1个表级锁,而取消这些行级锁)
(f)与锁相关的数据字典
V$LOCK视图/DBA_LOCKS视图:所有会话保持或申请的锁的信息
V$LOCKED_OBJECT视图:所有会话锁定的对象以及使用的锁的模式
DBA_WAITERS视图:显示所有被阻塞会话及其申请的锁和阻塞该会话的会话保持的锁的信息
DBA_BLOCKERS视图:显示阻塞了其他会话的那些会话
V$LOCK视图的各个列的说明如下:
列名 数据类型 说明
ADDR RAW(4) 在内存中锁定的对象的地址
KADDR RAW(4) 在内存中锁的地址
SID NUMBER 保持或申请锁的会话的标识号
TYPE VARCHAR2(2) 锁的类型:TX=行锁或事务锁;TM=表锁或DML锁;UL=PL/SQL用户锁
ID1 NUMBER 锁的第1标识号。TM锁,该值表示将要被锁定的对象的标识号;TX锁,该值表示撤销段号码的十进制值
ID2 NUMBER 锁的第2标识号:TM锁,该值为0;TX锁,该值表示交换次数
LMODE NUMBER 会话保持的锁的模式。0=None;1=Null;2=Row-S (SS);3=Row-X (SX);
4=Share;5=S/Row-X (SSX);6=Exclusive
REQUEST NUMBER 会话申请的锁的模式。与LMODE中的模式相同
CTIME NUMBER 以秒为单位的,获得当前锁(或转换成当前锁的模式)以来的时间
BLOCK NUMBER 当前锁是否阻塞另一个锁。0=不阻塞;1=阻塞
(g)死锁
当Oracle检测到死锁后,会在跟踪文件中记录下死锁的信息。
Oracle跟踪文件分为三种类型,一种是后台报警日志文件,记录数据库在启动、关闭和运行期间后台进程的活动情况,如表空间创建、回滚段创建、某些alter命令、日志切换、错误消息等。在数据库出现故障时,应首先查看该文件,但文件中的信息与任何错误状态没有必然的联系。后台报警日志文件保存BACKGROUND_DUMP_DEST参数指定的目录中,文件格式为AL
alert_SID.log。
另一种类型是DBWR、LGWR、SMON等后台进程创建的后台跟踪文件。后台跟踪文件根据后台进程运行情况产生,后台跟踪文件也保存在BACKGROUND_DUMP_DEST参数指定的目录中,文件格式为siddbwr.trc、sidsmon.trc等。
还有一种类型是由连接到Oracle的用户进程(Server Processes)生成的用户跟踪文件。这些文件仅在用户会话期间遇到错误时产生。
此外,用户可以通过执行oracle跟踪事件(见后面)来生成该类文件,用户跟踪文件保存在USER_DUMP_DEST参数指定的目录中,文件格式为oraxxxxx.trc,xxxxx为创建文件的进程号(或线程号)。
例如: