Bai_yk的gravatar头像
Bai_yk 2016-08-02 11:11:55

Java多线程高并发批量插入oracle数据导致主键ID冲突如何解决?

我的问题是这样的,用的框架和DB是SpringMVC+Mybatis+oracle,通过线程池开了五个线程。操作的数据分成五份,分别交给五个线程去处理。最后导致插入oracle数据库的时候出现主键不唯一(通过序列获取)。在插入方法之上也用了synchronized,但是不知道为啥锁不住,还是有多个线程同时去执行这个方法。

以下代码片段是我的线程池操作

Java多线程高并发批量插入oracle数据导致主键ID冲突如何解决?

 

以下是线程Run方法中要去执行的插入方法Java多线程高并发批量插入oracle数据导致主键ID冲突如何解决?

Mybatis配置

Java多线程高并发批量插入oracle数据导致主键ID冲突如何解决?

报错信息

Java多线程高并发批量插入oracle数据导致主键ID冲突如何解决?

所有回答列表(9)
最代码官方的gravatar头像
最代码官方  LV167 2016年8月2日

我这边建议先申请id,然后将该id作为记录主键再插入。

该id一定要支持高并发并且可以用来排序,所以uuid的生成是合适的,考虑到分布式id的话建议用twitter的idworker算法。

参考想找一个java版本的twitter的IdWorker的代码

zlczhou的gravatar头像
zlczhou  LV4 2016年8月3日

我没看明白问题

lhrce的gravatar头像
lhrce  LV9 2016年8月4日

序列能先缓存么

zhangxvle的gravatar头像
zhangxvle  LV4 2016年8月4日

楼主,把 listUtil类代码贴出来看看怎么把数据分份的

goodsave的gravatar头像
goodsave  LV2 2016年8月4日

你好,我们现在也是在做这块,分享一下我们的经验:

你需要在目标库中建立timestamp字段,借助timestamp属性(行的标识列)来做到唯一性

另外你的insertuser方法最好是静态方法,

此外 ReentrantLock 拥有Synchronized 相同的并发性和内存语义,并且多了锁投票,定时锁等候和中断锁等候,建议用ReentrantLock

最后就是你的原数据主键id的划分需要注意不要重复,目标库可以不设自增

现在上班时间手写的,希望给分!

Nero丶的gravatar头像
Nero丶  LV9 2016年8月4日

之前用oracle自带的sequence...可以尝试下。。不知道满不满足你

林銮建的gravatar头像
林銮建  LV7 2016年8月4日

可以先把系列缓存

zdd123456的gravatar头像
zdd123456  LV9 2016年10月8日

楼主,把 listUtil类代码贴出来看看怎么把数据分份的

Bai_yk的gravatar头像
Bai_yk  LV17 2016年10月8日

分割代码工具类(仅供参考,有些业务场景可能不适用)。贴图贴出来比较好看一点

Java多线程高并发批量插入oracle数据导致主键ID冲突如何解决?

顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友