您好,欢迎访问一九零五行业门户网

图文详解Oracle锁表解决方法的详细记录

本篇文章给大家带来了关于oracle的相关知识,在开发oracle数据库时,我们常遇到频繁操作的oracle数据表,会出现oracle锁表,下面给大家介绍了关于oracle锁表解决方法的相关资料,希望对大家有帮助。
推荐教程:《oracle视频教程》
锁表或锁超时相信大家都不陌生,经常发生在dml语句中,产生的原因就是数据库的独占式封锁机制,当执行dml语句时对表或行数据进行锁住,直到事务提交或回滚或者强制结束当前会话。
对于我们的应用系统而言锁表大概率会发生在sql执行慢并且没有超时的地方(一条sql由于某种原因(spoon工具做数据抽取与推送)一直执行不成功并且一直不释放资源)因此写出高效率sql也尤为重要!还有另外情况也会发生锁表,就是高并发场景,高并发会带来的问题就是spring事务会造成数据库事务未提交产生死锁(当前事务等待其他事务释放锁资源)!从而抛出异常java.sql.sqlexception: lock wait timeout exceeded;。
那么如何解决锁表或锁超时呢?临时性解决方案就是找出锁资源竞争的表或语句,直接结束当前会话或sesstion,强制释放锁资源。例如
解决方法如下:1、session1修改某条数据但是不提交事务,session2查询未提交事务的那条记录
2、session2尝试修改
我们可以看到修改未提交事务的记录会处于一直等待状态,直到对方释放锁资源或强制关闭session1。这里也说明了oracle做到了行级锁!
这里只是简单的模拟了出现锁表情况,可以一眼看出就是session1导致的锁表。实际开发中遇到这种情况一般都是使用sql直接查出锁资源竞争的表或语句然后进行资源的强制释放!!
3、session3查询竞争资源的表或语句,强制释放资源
-- 查询未提交事务的session信息,注意执行以下sql,用户需要有dba权限才行select l.session_id, s.serial#, l.locked_mode as 锁模式, l.oracle_username as 所有者, l.os_user_name as 登录系统用户名, s.machine as 系统名, s.terminal as 终端用户名, o.object_name as 被锁表对象名, s.logon_time as 登录数据库时间from v$locked_object l inner join all_objects o on o.object_id = l.object_id inner join v$session s on s.sid = l.session_idwhere 1 = 1
查询结果如下
对我们强制释放资源有用的只有前面两个字段,例如
-- 强制 结束/kill 锁表会话语法alter system kill session 'session_id, serial#';-- 强制杀死session1,让session2可以修改id=5的那条记录alter system kill session '34, 111';
强制杀死session1后,注意观察session2的执行情况!我们会发现session2的等待会立即终止并执行!相信小伙伴们都有一个疑惑,session_id有29和34,如何确定他们属于session1还是session2,保证杀死的是session1让session2成功执行dml语句?
其实也很简单,这里的判断方式就是session1执行更新但不提交事务,可先用以上sql查询未提交事务的session信息,此时查到的就是session1的信息。
推荐教程:《oracle视频教程》
以上就是图文详解oracle锁表解决方法的详细记录的详细内容。
其它类似信息

推荐信息