记一次java实现mysql的批量更新

本文记录了一次通过Java优化MySQL批量更新的过程。首先尝试使用线程池更新,但未能解决频繁数据库交互问题。接着引入队列,利用Spring定时任务进行批量更新,但存在控制队列大小的挑战。最后,采用阻塞队列配合守护线程,当任务达到5000条或超时30秒时执行批量更新。同时,文章提到了MySQL批量更新的两种方式,但由于公司数据连接中间件限制,最终选择了第一种方式。
摘要由CSDN通过智能技术生成

背景

项目中开发一个任务执行模块以下简称执行模块,由别的模块调用执行模块计算任务的结果,计算完成后需要把结算结果、计算状态、计算耗时等信息更新到Mysql库里,执行模块是来一个任务执行一次更新一次,后来发现这样需要频繁的与Mysql交互,且需要等待写库结果返回,效率堪忧拖慢其他模块。

优化

第一步:用线程池来更新,将更新代码提交到线程池中,由线程池调度入库
缺点:没有解决与数据库频繁交互的问题。
第二步:执行模块不管更新结果,只需将更新任务放入一个队列中然后直接返回;用Spring的定时任务注解@Scheduled,指定一个方法,隔一段时间调用一次入库方法;入库的逻辑是,获取队列当前任务个数cnt,循环poll任务然后添加到一个List中,poll够cnt个之后,通过批量更新方法将List更新到数据库。
缺点:定时执行无法控制队列大小,可能一次会取出很多条任务,也可能会把队列撑得过大。
第三步:使用阻塞队列放更新任务,用守护线程poll的队列中的任务,当条数等于5000条(此值根据实际情况),则批量更新一次,在poll时设置超时时间为30秒,当超过30秒还是没有取到任务,则也批量把已经渠道的任务更新一次。

总结:没有三板斧都不好意思写代码!!!

队列实现

@Service
public class JobExecutorDataServiceImpl {
   
    //定义一个容量为10000的阻塞队列,BlockingQueue线程安全可以多个生产者同时put
    private BlockingQueue<Job> dataQueue = new LinkedBlockingQueue<>(10000);

    //put任务的方法,供生产者调用
    public void recordJob(Job job) {
        try {
            dataQueue.put(job);
        } catch (InterruptedException e) {
            LOGGER.info("批量更新Job入队列异常");
            Thread.currentThread().interrupt();
        }
    }

    //初始化即调用
    @PostConstruct
    private void batchUpdate() {
        Thread thread = 
  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值