目录
项目场景:
问题描述
原因分析:
解决方案:
其他解决方案:
项目场景:
oracle 数据库在做大量的批量更新同一张表数据。
问题描述
早上来公司去生产环境查grelog日志,发现ERROR日志,点进去看后报如下错误:
ORA-00060: deadlock detected while waiting for resource
原因分析:
从错误的中一看就知道oracle 数据库发生了死锁。去生产的log日志查看,发现同一时间点左右,还有一个批量更新同一条数据的慢sql 日志。这个慢sql 的更新和这个死锁的sql 更新互斥了。导致了死锁。 死锁的异常抛出后,这个慢sql 就执行成功了。
在本地也写单元测试实例,跑出了同样的结果。猜测是因为更新主键SequenceNo更新时乱序导致的死锁。
解决方案:
在执行批量更新前,先对主键序列号进行排序,然后在进行批量更新。
例如:A线程更新的主键是1,2,3 B线程更新的主键是3,2,1 当批量更新时就可能会死锁,但是排序后,A线程更新的主键是1,2,3 B线程更新的主键是1,2,3 这是就不会产生死锁,测试过。这种情况多线程,跑了两天也没发生过死锁。
代码如下:
objects.stream().sorted((a1, a2) -> a1.getSequenceNo().compareTo(a2.getSequenceNo()));
int[] execute = dsl.batchUpdate(objects.stream().map(i -> {
ARecord r = new ARecord();
r.setSequenceNo(i.getSequenceNo());
r.setTime(i.getTime());
r.setResult(i.getResult());
r.changed(table.SEQUENCE_NO, false);
return r;
}).collect(Collectors.toList())).execute();
return Integer.parseInt(String.valueOf(Arrays.stream(execute).count()));
其他解决方案:
当时讨论的还有其他解决方案,如下:
1 可以更新前加锁,避免导致死锁
2 可以把批量更新成单条更新操作文章来源:https://www.toymoban.com/news/detail-585148.html
但是通过分析发票,这些方案都是会影响程序的性能,导致性能变慢,还有对代码的修改比较大,有很大的不确定性和风险。综上综合考虑选择批量更新前排序解决次问题。文章来源地址https://www.toymoban.com/news/detail-585148.html
到了这里,关于解决oracle死锁,生产问题,ORA-00060: deadlock detected while waiting for resource,的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!