Oracle12C--锁(十二)

来源:互联网 发布:单片机modbus主机程序 编辑:程序博客网 时间:2024/06/05 14:33

知识点的梳理:

1.   此语法要结束一个session(结束session就表示解锁),则需要两个标记,一个是session id(sid),另外一个是序列号(serial#),这两个内容可以利用“v$locked_object”和“v$session”两个数据字典查询到

alter system kill session 'sid,serial#'

2.   程序出现锁定后,使用管理员账号(sys/change_on_install),查看数据库中死锁占用资源的sql语句

SELECT session_id,oracle_username,process fromv$locked_object ;

3.    只知道一个session_id,不知道序列号,是无法结束死锁的。还要查询v$session数据字典

SELECT sid,serial#,username,lockwait,status FROM v$sessionwhere sid IN (sid1,sid2) ;

4.    当多个事务同时操作同一资源时,就会出现死锁的情况,锁分为两种。行级锁定,表级锁定;


什么是锁?

1.    事务可以保证数据的完整性以及有效性,但事务所采用的核心操作是“锁”;

2.    如:某一个session在更新数据库时,会将所操作的数据或数据表进行锁定,其他的session必须等待当前用户解锁后(提交或回滚),才可以进行自己的操作,而这种等待的过程,可以理解为锁


基础示例

--还是开启两个cmd,使用同一账号登录sqlplus--第一个session(c##scott/tiger连接)执行以下操作:SELECT * FROM myemp WHERE deptno=10 FOR UPDATE ;--效果:控制台会打印出一些数据


--第二个SESSION(c##scott/tiger连接)执行同样的操作。SELECT * FROM myemp WHERE deptno=10 FOR UPDATE ;--效果:控制台并没有向下执行,而是出于等待状态。这个时候只有在第一个session执行了commit或rollback后,才可以解开这个锁定 


这种关系如下图: 锁机制可以很好的解决并发问题


Oracle锁的两种基本类型

行级锁定(记录锁定):对当前事务中的一行数据以独占的方式进行锁定,在此事务结束之前,其他事务要一直等待该事务完结;

       排它锁:当用户执行了insert,update,delete以及select fro update语句时,Oracel隐式实现记录的锁定

                     特点:一个事务执行了相应的数据操作后,此事务没有提交,会一直以独占的方式锁定这些操作的数据。其他事务一直到此事务释放锁后才可以进行操作

        

--示例:第一个session更新雇员编号是7369雇员的工资
--该更新操作可以正常执行完毕,但没有提交时,7369雇员的数据将会以独占的方式进行行级锁定;UPDATE myemp SET sal=5600 WHERE empno=7369 ;
--第二个session更新雇员编号是7369雇员工作UPDATE myemp SET job='MANAGER' WHERE empno=7369 ;--此时由于第一个session的事务没有提交,所以第二个session就会一直等待第一个session的事务提交或者回滚


表级锁定:对整张数据表进行数据锁定,只允许当前事务访问数据表,其他事务无法访问;

--该锁定需要用户明确使用lock table语句手工锁定,lock table语句如下:
lock table 表名称 | 视图名称,表名称 | 视图名称,...in 锁定模式 mode [nowait];

owait选项:可选项,当视图锁定一张数据表时,如果发现已经被其他事务锁定,不会等待;

锁定有如下几种常见模式:

1.    row share:行共享锁,在锁定期间允许其他事务并发对表进行各种操作,但不允许任何事务对同一张表进行独占操作(禁止排它锁);

2.    row exclusive:行排它锁,允许用户进行任何操作,与行共享锁不同的是,它不能防止其他事务对同一张表进行手工锁定或独占操作;

3.    share:共享锁,其他事务只允许执行查询操作,不能执行修改操作;

4.    share row exclusive:共享排它锁,允许任何用户进行查询操作,但不允许其他用户使用共享锁;

5.    exclusive:排它锁,事务将以独占方式锁定表,其他用户允许查询,但是不能修改也不能设置任何的锁;


--示例:在第一个SESSION上针对于emp表使用共享锁,对表进行锁定LOCK TABLE myemp IN SHARE MODE NOWAIT ;

--此时,使用第二个SESSION删除emp表全部数据,会发现表已经锁定;DELETE FROM myemp ;


 解除锁定

--解除锁定语法:此语法要结束一个session(结束session就表示解锁),则需要两个标记,一个是session id(sid),另外一个是序列号(serial#),这两个内容可以利用“v$locked_object”和“v$session”两个数据字典查询到
alter system kill session 'sid,serial#'

--示例1:第一个SESSION(c##scott/tiger连接)执行以下操作SELECT * FROM myemp WHERE deptno=10 FOR UPDATE ;
--第二个SESSION(c##scott/tiger连接)执行同样的操作。进入锁定状态SELECT * FROM myemp WHERE deptno=10 FOR UPDATE ;
--程序出现锁定后,使用管理员账号(sys/change_on_install)可以直接利用"v$locked_object"查看数据库中死锁占用资源的情况SELECT session_id,oracle_username,process from v$locked_object ;
--此处有一个死锁信息,而死锁的session_id为6和14,依靠这两个id来接触死锁。但是只知道一个session_id,不知道序列号,是无法结束死锁的



--查询v$session数据字典SELECT sid,serial#,username,lockwait,status FROM v$session where sid IN (6,14) ;-目前等待的sessionsid14serial#6518,现在来解除死锁

--解除死锁ALTER SYSTEM KILL SESSION '14,6518' ;

 解除锁定后,session2的cmd会出现如下提示:








0 0
原创粉丝点击