oracle的锁
锁是管理共享资源的并发访问。
1 关于锁的衍生概念
1.1 悲观锁
悲观锁是认为数据会被其他会话同时修改。所以在数据修改前,先对数据锁定,然后再修改数据。例如,先对某一行数据进行for update锁定,然后再更新这一行的数据。
Select * from table where primary_key = :primary_key And decode( columnl, :old_columnl, 1)=1 And decode( column2, :old_column2, 1)=1 For update;
Update table Set columnl = :new_columnl, column= :new_column2, Where primary_key = :primary_key;
Commit;
1.2 乐观锁
乐观锁是认为数据不会别其他会话同时修改。所以只有在执行修改数据语句时才对数据进行锁定。例如,对某一行数据直接进行修改
Update table Set columnl = :new_columnl, column= :new_column2 Where primary_key = :primary_key And decode( columnl, :old_columnl, 1)=1 And decode( column2, :old_column2, 1)=1;
1.3 阻塞
当一个会话持有某个资源,另一个会话访问这个这个资源时,就会出现阻塞。
1.4 死锁
两个会话互相等待对方释放资源就会出现死锁。
2 oracle锁类型
2.1 DML锁
当执行select,update,insert,delete,merge时对数据的锁定就属于DML锁。DML锁分为TX锁和TM锁。
2.1.1 TX锁
TX锁是一个行级锁。当事务获取到TX锁时,会一直持有,直到事务结束。在oracle中,锁是数据的一个属性。事务对行数据锁定时,行会对应一个事务ID,这个事务ID存放在块中。别的事务访问同样的行时,会查看行对应的事务id,检查事务是否是活动的。如果事务活动,则等待事务结束,要求原来的事务一旦释放锁,进行通知。所以会有一个锁的排队队列。如果事务不活动,则对行进行锁定,获得TX锁。
2.1.2 TM锁
TM锁是数据进行DML操作时,会对表进行锁定,防止其他会话修改表结构。
2.2 DDL锁
当执行DDL操作时,操作的对象就会产生DDL锁,防止其他会话修改操作对象的结构
3 闩
闩是对orale内存结构保护的一种串行化设备。用于对数据库高速缓存、共享池等内存结构并发访问的协调管理。例如一个查询的硬解释,就会用到闩。一个会话对某个内存结构进行修改时,其他会话无法对该内存结构进行读取。当一个会话释放闩时,闩的分配是随机,每个请求闩的起他会话都有可能获取到闩。等待闩的会话不会排队,只是不断进行重试。
4 闩和队列锁区别
队列锁允许会话以队列的方式等待释放锁,会发生堵塞。而对于闩,如果会话不能获取到闩,不是等待闩的释放,而是稍后重试,尝试得到闩。
5 手动锁定和用户定义锁
5.1 手动锁定
当我们先手动锁定一些行数据时,可以使用select ...for update的方式进行锁定。其他会话就无法修改我们select选中的数据
5.2 用户定义锁
当我们需要锁定一些oracle数据外部的资源时,例如外部文件。可以通过DBMS_LOCK包进行锁定