Oracle中的锁:
锁是数据库用来控制共享资源并发访问的机制。
锁用于保护正在被修改的数据
直到提交或回滚了事务之后,其他用户才可以更新数据
行级锁
对正在被修改的行进行锁定,其他用户可以访问除被锁定的行以外的行
在使用insert,delete,update,select…for upadte语句时,Oracle会自动应用行级锁
Select…for update语句允许用户一次锁定多条记录进行更新,可以限制用户等待的时间及防止无限期等待
用户必须通过commit或rollback语句释放锁
表级锁
将整个表锁定 Lock table 表名 in share mode;
锁的类型
1. 共享锁--查询
一个表的数据所有人都可以使用
2. 独占锁
一个表的数据已被一个用户占用,其它人不能使用
3. 共享独占锁(行级锁)
一个用户可以占用一张表中的一些记录
4. 不等待
select * from bank where bankid=1000 for update nowait;
2)释放锁:提交 commit 或 回滚 rollback
Oracle锁机制
数据库都有并发机制,不过带来的问题就是数据访问的冲突。
为了解决这个问题,大多数数据库用的方法就是数据的锁定。
数据的锁定分为两种方法:第一种叫做悲观锁,第二种叫做乐观锁
悲观锁
悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,
也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住,
没有提交或者回滚事务前都不能操作这些数据
示例用SCOTT.class表
先将SCOTT.class的修改权限赋给xiaoming这个用户
grant update on class to xiaoming;
然后使用for update将id为2的数据锁住
select * from class where classid=2 for update;
重新开一个sqlplus,使用xiaoming登录
修改修改id为2的数据
update scott.class set cname='a' where classid=2;
这时候我们会看到一直卡在这里,操作堵塞了:
切换到SCOTT的sqlplus下,使用commit提交事务
这时候xiaoming的update操作才能完成
但是这样的操作会导致所有操作带锁的数据时,都要排队,效率会低下
乐观锁
乐观锁就是一开始假设不会造成数据冲突,在最后提交的时候再进行数据冲突检测
像我们后面学习的数据访问层的hibernate框架里就实现了乐观锁。
Oracle默认使用乐观锁。
总结:
1. 如果系统并发量不大且不允许脏读,可以使用悲观锁解决并发问题。
2. 如果系统并发非常大的话,悲观锁会带来很大性能问题,所以一般采用乐观锁。
3. 如果系统读比较多,写比较少,也应该使用乐观锁,可以提高吞吐量。
死锁
用户a操作a表,加锁
用户b操作b表,加锁
两个用户都没有提交事务释放锁,这时候
a操作b表,等待b表解锁
b操作a表,等待a表解锁
这就形成了死锁
死锁一般需要在程序设计时就避免掉
解决死锁
select sql_text from v$sql where hash_value in (select sql_hash_value from v$session where sid in (select session_id from v$locked_object));
查出以下语句死锁:
delete from testLock where ID = 1
死锁的处理:alter system kill session 'session_id,serial#';
alter system kill session '301,16405';
再查看一下死锁,会发现已经没有stauts为active的记录了,发生死锁的语句已经被终止。