Posted on 2010-02-19 22:23
landor 阅读(1506)
评论(0) 编辑 收藏 所属分类:
oracle
oracle的锁并没有锁升级,也就是无论有多少行数据被锁定也不会升级到表锁,这和sqlserver完全不一样
oracle锁类型包括:DML锁、DDL锁、内部锁和闩
DML锁:数据库操作语言锁,比如insert、delete、update语句引发的锁。当进行上述操作时,会出现两种DML锁:
TX锁:事务锁,当事务发起第一次修改时会出现TX锁,直到事务的提交或回滚时释放锁,当执行select for update的时候也会引发;
TM锁:当数据被修改时,为防止出现表结构的变化,比如alter、drop操作,所加的锁,这时如果有其他事务修改表结构,会返回错误信息ORA-00054。
TX锁:当修改表中某一行或者某十行数据时,会在包含该数据的块中记录当前事务的id。此时如果另会话2进入,要修改当前记录时,会检查当前块中的事务id,然后到事务表中查看该事务是否活动,如果不活动,那么会话2会修改该行并锁定该行;如果活动那么会话2会发出一个request,要求会话1释放锁的时候通知会话2一声。
这里涉及到了3个表:V$TRANSACTION(事务表),V$SESSION(会话表)、V$LOCK(锁信息)
这里记录一下V$LOCK表,这里面的记录是针对表和会话的,而不是针对行的,如果表有1条记录被锁定,那么V$LOCK中会有一条记录,如果表中有10条记录被锁定,那么V$LOCK中还是一条,因为它是针对于会话的。
在表V$LOCK的SID就是会话id,而通过id1和id2可以匹配到V$TRANSACTION中的事务id
举个例子:如果事务1锁定了一个表的10行记录,那么V$LOCK中会有一条记录,其中LMODE为6,表示排他锁,REQUEST为0,表示事务1并没有发出请求,也就是说事务1可以拥有这个锁;
此时事务2也要锁定这10行记录中的若干行,结果发现该行已经被事务1锁住了,事务2只能向事务1发出请求REQUEST=6,意思是事务2向事务1发出一个排他锁的请求,此时在V$LOCK表中有三条记录,一条是事务2的排他锁,一条是事务2向事务1发出的request请求,一条是事务1的排他锁。当事务1提交或者回滚释放锁后,V$LOCK中事务2的那个请求行消失,事务2获取了该行的排他锁。
DDL锁:数据库定义语言锁,当进行表的alter等操作时,会触发该锁,防止其他会话(session)获取到这个表的DDL锁或者DML锁中的TM锁。
DDL语句是总是提交的,比如有3个alter语句,那么每个都是自动提交的,比如第二个出现错误,那么第一个也已经提交了,无法回滚了
关于oracle的事务处理
ACID是下面的4个词:
原子性:事务中的所有动作要么都发生,要么都不发生
一致性:事务将数据库从一种状态转换为另一种状态
隔离性:一个事务的影响在该事务提交前,对其他事务是不可见的
持久性:事务一旦提交,其影响的结果是永久的
分布式事务:
oracle使用了一个协议,叫2pc协议(两阶段提交two-phase commit),如果同时修改多个数据库,那么其中一个数据库(比如数据库1)会成为事务的发起者和协调者,具体操作如下:
1 数据库1会询问其他所有数据库的事务是否已经准备完毕了
2 数据库2和数据库3分别报告说已经ok了
3 数据库1会广播一条信息,让所有数据库都知道其他数据库的事务已经ok了,可以提交自己的事务了
如果有一个数据库报告的是no,那么事务1会发出消息,让所有事务回滚
如果在数据库2和3都返回ok的时候,数据库1马上要广播给其他数据库,结果发生掉电等问题了,那么数据库2和数据库3的事务都会挂起等待事务1的消息,此时就会出现可疑事务,这种事务就需要人工处理了。