关于Oracle的锁机制

-【ORACLE锁机制】
-数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

-加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

-在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。

-【锁类型】
DML锁(data locks,数据锁),关键字:select、Insert、delete、update...,用于保护数据的完整性;主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁
DDL锁(dictionary locks,字典锁),关键字:create table、alter table、drop...,用于保护数据库对象的结构,如表、索引等的结构定义;
内部锁和闩(internal locks and latches),保护 数据库的内部结构

-【悲观封锁和乐观封锁】
-悲观封锁:锁在用户修改之前就发挥作用
-乐观封锁:乐观认为数据在select出来到update进取并提交的这段时间数据不会被更改。Oracle仍然建议是用悲观封锁,因为这样会更安全

--测试锁表sql
--【SELECT ... FOR UPDATE命令】手动锁定,行级封锁,这种锁定方式是建立在数据库连接的基础上,一旦连接断开或者锁定进程commit时,这种锁定就自动解除。
select * from carseries2 where id<100 for update;                   --锁定select出来的所有行

--【for update of columns】 
--多表连接锁定时,指定要锁定的是哪几张表,而如果表中的列没有在for update of 后面出现的话,就意味着这张表其实并没有被锁定,其他用户是可以对这些表的数据进行update操作的。不指定则全锁
select t1.*,t2.* from carseries2 t1 left join carmodel t2 on t2.carseriesid=t1.id where t1.id<100 for update of t1.name;   
  
--[WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待]
select t.* from carseries2 t where t.id<100 for update nowait;        --如果其他进程锁定了记录,避免被挂起(死锁),添加【nowait】
select t.* from carseries2 t where t.id<100 for update wait 5;        --如果记录锁定了,等待5秒。5秒后报异常
select t.* from carseries2 t where t.id<100 for update nowait skip Locked; --立即执行sql时,即不等待,也不报资源忙异常。


//【查询被锁表信息】 --http://blog.csdn.net/u013991521/article/details/53535818
select t2.username oracle用户名,
       t2.sid 进程号,
       t2.serial# 序列号 ,
       t3.object_name 表名,
       t2.OSUSER 操作系统用户名,
       t2.MACHINE 机器名 ,
       t2.PROGRAM 操作工具 ,
       t2.LOGON_TIME 登陆时间,
       t2.COMMAND,
       t2.LOCKWAIT 是否正在等待解锁 ,
       t2.SADDR,
       t2.PADDR,
       t2.TADDR,
       t2.SQL_ADDRESS,
       t1.LOCKED_MODE 锁表模式
  from v$locked_object t1, v$session t2, dba_objects t3
 where t1.session_id = t2.sid
   and t1.object_id = t3.object_id
 order by t2.logon_time;
 
/********************************************************************【LOCKED_MODE 锁表模式】***************************************************/ 
--数字越大锁级别越高, 影响的操作越多。
//0:none              
//1:null 空           --Select,有时会在v$locked_object出现。
 
//2:Row-S 行共享(RS):行级共享锁,sub share --Select for update,Lock For Update,Lock Row Share,select for update当对话使用for update子串打开一个游标时,所有返回集中的数据行都将处于行级(Row-X)独占式锁定,其他对象只能查询这些数据行,不能进行update、delete或select for update操作。 

//3:Row-X 行独占(RX):行级排它锁,sub exclusive        --Insert, Update, Delete, Lock Row Exclusive,没有commit之前插入同样的一条记录会没有反应, 因为后一个3的锁会一直等待上一个3的锁, 我们必须释放掉上一个才能继续工作

//4:Share 共享锁(S):共享锁,阻止其他DML操作,share              --Create Index, Lock Share ,

//5:S/Row-X 共享行独占(SRX):共享行级排它锁,阻止其他事务操作,share/sub exclusive    --Lock Share Row Exclusive,具体来讲有主外键约束时update / delete … ; 可能会产生4,5的锁。 

//6:exclusive 独占(X):排它锁,独立访问使用,exclusive      --Alter table, Drop table, Drop Index, Truncate table, Lock Exclusive
 /************************************************************************************************************************************************/ 
 
--查出锁定表的session的sid, serial#,os_user_name, machine name, terminal和执行的语句
SELECT l.session_id sid, s.serial#, l.locked_mode, l.oracle_username, s.user#,
l.os_user_name,s.machine, s.terminal,a.sql_text, a.action
FROM v$sqlarea a,v$session s, v$locked_object l
WHERE l.session_id = s.sid
AND s.prev_sql_addr = a.address
ORDER BY sid, s.serial#;

--查找到数据库中所有的DML语句产生的锁,任何DML语句其实产生了两个锁,一个是表锁,一个是行锁。
SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine,
s.terminal, s.logon_time, l.type
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
ORDER BY sid;



--【kill锁】ps:不要自杀,需要新建SQL窗口执行
//alter system kill session 'sid,seial#';

alter system kill session '1064,5785';



--查某session 正在执行的sql语句
SELECT  sql_text  FROM v$sqltext a
 WHERE (a.hash_value, a.address) IN 
 (SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),DECODE(sql_hash_value, 0, prev_sql_addr, sql_address) FROM v$session b WHERE b.sid = '1085')  /* 此处1085 为SID*/
 ORDER BY piece ASC;
 


 
-【ORACLE定期清理INACTIVE会话】
--http://www.cnblogs.com/kerrycode/p/3636992.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值