1.什么是锁
数据库是一个庞大的多用户数据管理系统, 同一时刻可能有多个用户同时操作。事务的分离性要求当前事务不能影响其他的事务,所以多个会话操作同一个资源时,数据库会利用锁确保他们像队列一样一次执行。利用来锁消除多个用户操作同一个资源产生的隐患。可以说,锁是一种机制,在访问相同资源时,可以防止事务之间的破坏性交互。Oracle处理数据时用到的锁是自动获取的,不需要对锁过多关注。
例如,当一个会话A对用户的账本金额做修改时,另一个会话B也要做修改账本金额操作。如果在没有任何处理的情况下就会出现脏读情况。如果使用了行级锁,会话A修改账本金额时锁改行,那么会话B就只能等待。这样就实现了依次处理
2.锁的分类
2.1 排它锁(X锁)
也叫写锁,这种模式防止资源共享,用作数据修改,如果事务T给数据A加上排它锁,那么其他事务就不能给A加任何锁。此时只允许事务T对数据做读取和修改
2.2 共享锁(S锁)
也叫读锁,这种模式只能被读取不能被修改。如果事务T给数据A加共享锁,那么其他事务不能给A加排它锁,只能加共享锁。加了锁的数据只能被共享读
3.锁的类型
3.1 内部闩锁
作用:保护数据库的内部结构。
3.2 DDL锁
DDL锁作用:可以保护模式中对象的结构。
DDL锁细分:
- Excluseve DDL Lock ,排他DDL锁,对象加锁后不能被其他会话修改,如果是表此时可以读取数据
- Shared DDL Lock,共享DDL锁,保护对象结构,会话不能修改对象结构,但是允许修改数据
- Breakable Parsed Lock,能打破的解析锁定。这个类型的锁可以被大断,不能禁止DDL操作
会话执行DDL操作时,Oracle会自动的提交一次事务,然后自动给处理对象加锁,当DDL结束时,Oracle会隐式提交事务并释放DDL锁。用DML不同,用户不能显示的使用DDL锁。
3.3 DML锁
DML锁作用:用户保护数据,主要保证访问时数据的完整性
DML锁细分:
- 行级锁(TX),也叫事务锁。当修改表中某行记录时。需要对将要修改的记录加行级锁。方式两个事务同时修改相同记录,事务结束锁释放,该锁属于排他锁
- 表级锁(TM),主要作用是防止在修改表的数据时,表的结构发生变化。例如会话S在修改表A的数据时它会得到表A的TM锁,而此时不允许其他会话对该表进行变更或者删除。
会话在做DML操作的时候,数据库会先申请数据对象上的共享锁,防止其他会话对此对象做DDL操作。一旦申请成功。 则会对要修改的记录申请排它锁。(如果此时其他会话正在修改数据,则等待其他事务结束后再增加排它锁)
4.锁等待和死锁
由于占用资源不能及时释放,会造成锁的等待。例如,当一个会话S1修改记录A,A被加锁,如果另一个会话S2也来修改记录A,那么第二个会话将得不到排它锁会一直等待,知道会话S1事务提交释放锁,会话S2才能对数据进行操作。
死锁是锁等待的一个特征,加入,当会话S1需要修改2个资源,这2个资源在同一个事务里,修改第一个对象A时对其加锁,修改第2个对象B时另一个会话S2获取了锁并锁定了B,等待A释放锁,那么就出现了死锁。
当出现死锁的时候可以使用下面的SQL尝试处理,例如下面是之前遇到的一个问题,SID869修改DICTEN表,且锁住了表。 SID1393尝试修改DICTEN表时死锁一直等待
-查询当前的被锁对象
SELECT l.session_id sid,
s.serial#,
l.locked_mode 锁模式,
l.oracle_username 登录用户,
l.os_user_name 登录机器用户名,
s.machine 机器名,
s.terminal 终端用户名,
o.object_name 被锁对象名,
s.logon_time 登录数据库时间
FROM v$locked_object l, all_objects o, v$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid
ORDER BY sid, s.serial#;
删除会话
--kill掉当前的锁对象语法格式
alter system kill session 'sid,s.serial#';
--例如:
alter system kill session '869,22889';
上一篇:Oralce ORA-00018超出最大会话数处理记录