Oracle的锁和阻塞
锁是由并发产生,并发(concurrency)指超过两个以上的用户对同样的数据做修改,可能包括插入,删除和修改。并行(parallel)指将一个任务分成很多小的部分,每一个部分同时执行,最后将执行结果汇总成最后的结果。
查看数据库中是否存在锁:
1. 查看会话SID:select sid from v$mystat where rownum=1;
2. 通过查看视图v$lock:select sid, type,id1,id2,lmode,request, block from v$lock where sid in([SID1],[SID2]) order by sid;
request列是一个非0的值,那么该SID就在等待一个锁,如果block列是1,那么这个SID就持有一个锁,阻塞了其他SID获得这个锁,这个锁类型由type定义,锁的模式由lmode定义,id1和id2定义了这个锁的相关信息。
3. 查询引起锁的用户信息:select machine from v$session where sid in ([SID1],[SID2]);
阻塞的原因:
1. 唯一性约束
2. 同时去修改数据,若前一个未提交,后一个去修改,使用select...for update的方式,以排他的方式获得这些需要修改行的数据,并且保证在修改完成前,其他用户无法对这些数据进行修改。
3. 外键没有创建索引,如果系统有主外键引用关系,并且满足以下三个条件中任意一个,那么就要考虑给外键建立索引,否则系统性能可能会下降甚至阻塞:
- 主表上有频繁的删除操作
- 主键上有频繁的修改操作
- 业务上经常会出现主表和从表做关联查询的情况
第一个条件和第二个条件操作的时候,主表会在从表上创建一个锁定,以保证主键的修改不会导致从表数据在引用上出现问题,这是一个数据引用完整性的要求。如果主表上经常出现删除或是对主键列进行修改的操作,或者每次操作的记录很多,都将造成从表长时间被锁定,而影响其他用户正常操作。比如主表每次删除1000行数据,它就需要扫描从表1000次,以确定每行记录的改变都不会造成从表数据引用上的不完整。如果在从表的外键上建立了索引,那么通过访问从表索引的方式在外键上查找相关的记录会极大提升性能,同时能避免从表被长时间锁定。