什么是锁
数据库是一个庞大的多用户数据管理系统,由于在多用户系统中,同一时刻多个用户同时操作某相同资源的情况时有发生,而在逻辑上这些用户想同时操作资源是不可能的,而数据库利用锁消除了多用户操作同一资源可能产生的隐患
锁出现在数据共享的环境中,它是一种机制,在访问相同资源时,可以防止事务之间破坏性交互。
锁的分类,Oracle分为两种模式的锁
- 排他锁(X锁),也叫写锁,防止资源共享,用于数据的修改,加入有事务对数据A加上该锁,那其他事务不能对A加任何锁,所以此时只允许T对该数据进行读取和修改,直到事务完成释放锁为止
- 共享锁(S锁),也叫读锁,这种模式下数据只能读取,不能修改,如果事务对数据A加了该锁,那么其他事务不能对其加上排他锁,只能加共享锁。加了该锁的数据可以被并发的读取。
锁的类型
- DML锁:该类型的锁被称为数据锁,用于保护数据
- 行级锁(TX) 也可以称为事务锁。当修改表中某行记录时,需要对将要修改的记录加上行级锁,属于排他锁
- 表级锁(TM)主要作用是防止在修改表的数据时,表的结构发生变化。会话S在修改表A的数据时它会得到表A的TM锁,而此时将不允许其他会话对该表进行变更或删除操作
- DDL锁:可以保护模式中对象的结构
- 内部闩锁: 保护数据库的内部结构,完全自动调用
在执行DML操作时,数据库会先申请数据对象上的共享锁,防止其他的会话对该对象执行DDL操作,一旦申请成功,会对将要修改的记录申请排他锁,如果此时其他会话正在修改该记录,那么等待期事务结束后再为修改的记录加上排他锁
表级锁报含如下几种模式:
- ROW SHARE 行级共享锁(RS)。该模式下不允许其他的并行会话对同一张表使用排他锁,但允许其利用DML语句或lock命令所得同一张表中的其他记录。select … from for update 语句就是给记录加上了RS锁
- ROW EXCLUSIVE 行级排他锁(RX)。该模式允许并行会话对同一张表的其他数据进行修改,但不允许并行会话对同一张表使用排他锁
- SHARE,共享锁(s),不允许会话更新表,但允许对表添加RS锁
- SHARE ROW EXCLUSIVE,共享行级排他锁(SRX).该模式下,不能对同一张表进行DML操作,也不能添加S锁
EXCLUSIVE,排他锁(X),该模式下,不能对表进行DML和DDL操作,该表只能读
RS | S | RX | SRX | X |
---|---|---|---|---|
RS | y | y | y | y |
S | y | y | x | x |
RX | y | x | y | y |
SRX | y | x | x | x |
X | x | x | x | x |
--主动添加TM锁
LOCK TABLE [SCHEMA.] TABLE IN
[EXCLUSIVE]
[SHARE]
[ROW EXCLUSIVE]
[SHARE ROW EXCLUSIVE]
[ROW SHARE* | SHARE UPDATE*]
MODE [NOWAIT]
--r如果要释放他们,只需要使用rowback命令
锁等待和死锁
在某些情况下有域占用的资源不能及时释放,而造成锁等待,也可以叫锁冲突,锁等待会严重影响数据库性能和日常工作。
死锁和等待不同,它是锁等待的一个特例,通常发生在空格或多个会话之间。假设一个会话想修改两个资源对象,修改这个两个对象在一个事务当中。当它修改第一个对象时需要对其锁定,然后等待第二个对象,这时如果另外一个会话也需要修改这两个资源对象,并且已经获得并锁定了第二个对象,那么就会出现死锁,因为当前会话锁定了第一个对象等待第二个对象,另一个相反,两个会话都不能得到向要的对象,就会出现死锁。
此时oracle自动做出处理,并重新回到锁等待的情况。出现锁等待的情况时应尽快找出错误并对其处理。主要原因有:
- 用户没有良好的编程习惯,偶尔忘记提交事务,导致长时间占用资源
- 操作的记录过多,而且操作过程没有很好的对其分组。前面介绍过,对于数据量很大的操作,可以将其分成几组提交事务。这样可以避免长时间地占用资源
- 逻辑错误,两个会话都想得到已占有的资源