1 锁冲突
锁冲突经常发生,但通常通过时间和排队机制解决。在某些罕见的情况下,锁冲突可能需要管理员干预。上图中事务2在9:00:00获得单个行上的锁,并忽略提交,将锁保留在适当的位置。事务1尝试在9:00:05更新整个表,要求对所有行进行锁。事务1被事务2阻塞,直到事务2在16:30:01提交。
在这种情况下,试图执行事务1的用户几乎肯定会联系管理员寻求帮助,DBA必须检测并解决冲突。
2 锁冲突的原因
锁冲突最常见的原因是未提交的更改,但也有一些其他可能的原因:
长时间运行的事务:许多应用程序使用批处理来执行批量更新。这些批处理作业通常在用户活动较少或没有用户活动的时候进行调度,但在某些情况下,它们可能没有完成,或者在活动较少的时候运行时间过长。当事务和批处理同时执行时,锁冲突很常见。
不必要的高锁级别:并非所有数据库都支持行级锁(Oracle在1988年发布的版本6中增加了对行级锁的支持),一些数据库仍然在页或表级锁。开发人员编写的应用程序要运行在许多不同的数据库上,他们常常使用人为的高锁定级别来编写应用程序,以便Oracle数据库的行为与这些性能较差的数据库系统类似。刚接触Oracle的开发人员有时也会在比Oracle数据库所需的更高的锁定级别上编写不必要的代码。
3 检测锁冲突
使用Enterprise Manager Cloud Control中的blocking sessions页面定位锁冲突。冲突的锁请求以层次结构布局显示,持有锁的会话在顶部显示,在其下方显示为锁排队的任何会话。
对于冲突中涉及的每个会话,将获得用户名、会话ID和会话等待的秒数。向下钻取SQL ID,查看会话当前正在执行或请求的实际SQL语句。
自动数据库诊断监视器(ADDM)还会自动检测锁冲突,并就低效率的锁定趋势提供建议。
4 解决锁冲突
要解决锁冲突,持有锁的会话必须释放锁。让会话释放锁的最好方法是联系用户并要求完成事务。
在紧急情况下,管理员可以终止持有锁的会话。请记住,当会话被终止时,当前事务中的所有工作都将丢失(回滚)。会话被终止的用户必须再次登录并重新执行自被终止会话上次提交以来的所有工作。
用户的会话已经被杀死收到以下错误,他们下次尝试发出一个SQL语句:
ORA-03135:失去联系
注意:PMON可以由于空闲超时而自动杀死会话。这可以通过使用profile或资源管理器来实现。
会话操作也可以通过发出SQL语句来完成。V$SESSION视图包含所有连接会话的详细信息。BLOCKING_SESSION中的值是正在阻塞的会话的会话ID。如果查询到SID和序列号#(其中SID匹配阻塞会话ID),那么就拥有了执行杀死会话操作所需的信息。
注意:数据库资源管理器可用于自动注销阻塞其他空闲会话的会话。