多线程4000W数据存储ORACLE出现死锁

thankjj20160909 2018-09-13 06:36:58
场景
对客户进行风险测评,客户量比较大,测评的话是根据客户的一些基本信息、交易信息去计算分数,比如倘若同一个客户某段时间内的交易次数超过5次,逻辑判断就会加上相应的分数。 现在采用多线程的,进行分批处理 ,假设100w客户,10个线程 ,单个线程处理量为5w 这样就会分为20个批次,10个线程同时进行,逻辑测评完 需要update客户表的某些字段,如分数等,需要插入每个客户的分数日志 ,还需要insert每个客户每道题对应的一个分数(单个客户会产生20条详情记录),附耗时主要是数据库的表操作。

多线程模型
if (exec == null){
exec = Executors.newFixedThreadPool(10); // 10个线程
}
for(int i = 0; i < 20; i++){
exec.execute("do sth"); // 测评已经分好批的客户,包括逻辑判断、表更新与插入
}
// 说明:线程内部缓存的客户,题目得分情况都是用的list,每次new的


问题
测评客户数量超过200W就会出现死锁啥的,报错java.sql.BatchUpdateException:ORA-00060:等待资源时检测死锁
查看ORCLE中发现得分详情表被锁住了,并且是三级锁

自我分析
网上看了挺多资料,ORACLE用的是行级锁,只是对想锁定的数据才进行锁定,其余的数据不相干,所以在对Oracle表中并发插数据的时候,基本上不会有任何影响。在这个场景中每个线程没有共享变量,数据都是线程内部获取,不会有任何冲突。

解决(不明不白)
将线程内部的list改为Vector就不会出现,一头雾水。难道线程内部创建的对象不是每个线程私有的吗?

求多线程大神指导,上述如果还有细节需要知道随时提供
...全文
537 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
thankjj20160909 2018-11-28
  • 打赏
  • 举报
回复
貌似是批处理数据量10000太大了,批次处理量改小一点可以
xian_s 2018-09-14
  • 打赏
  • 举报
回复
从死锁情况来看,是批量更新的时候,批次间存在重复数据导致了死锁。更具体的原因需要看下取数逻辑
thankjj20160909 2018-09-14
  • 打赏
  • 举报
回复
引用 1 楼 xian_s 的回复:
从死锁情况来看,是批量更新的时候,批次间存在重复数据导致了死锁。更具体的原因需要看下取数逻辑
发生死锁的表操作逻辑是存在先删再插,不存在直接插。这边因为一开始进行了分批,也就是说每个线程处理的是某一段数据,不存在线程之间有重复数据

51,409

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧