【问题标题】:How to persist entities using multiple processing threads with JPA and Hibernate如何通过 JPA 和 Hibernate 使用多个处理线程来持久化实体
【发布时间】:2015-04-04 23:03:10
【问题描述】:

有一个作业在单线程环境中运行。这意味着我有 main 方法,主线程负责完成工作。

我正在使用 Spring 和 Hibernate。

在高层次上,我正在执行以下步骤:

  1. 使用 JDBC 从 MySQL 数据库中获取数据(循环结果集并执行第 2. 和 3. 点)

  2. 使用从第 1 点收到的数据填充模型。

  3. 验证、调用服务层、dao层以及在oracle db中存储实体。

此流程使用for 循环。所以1对1的数据插入就在那里。

现在我想用多线程来做。

方法:

  1. 一个线程将获取数据并填充模型对象并将其放入队列中。

  2. 多个线程将从队列和起点 3 中取出对象。

你能帮我实现这个模型吗?如何编写这种类型的多线程框架。

【问题讨论】:

  • 可以使用风暴拓扑,可以为bolts设置不同的并行度(N个执行器)来做快速处理。它也支持分布式计算/容错/保证消息处理。很容易实现。现有的 java 代码将在那里重用。
  • 每个逻辑步骤的 Spring 线程池执行器怎么样?

标签: java multithreading spring hibernate transactions


【解决方案1】:

你可以这样做:

  1. 定义一个ExecutorService:

     ExecutorService executorService = Executors.newFixedThreadPool(10);
    
  2. 每个for 迭代都应该简单地提交要插入的新对象

     final RecordDTO record = ...;
     executorService.execute(new Runnable() {
         public void run() {
             insertService.save(record);
         }
     });
    
  3. insertService 将有一个 @Transactional save 方法使用这 10 个工作线程之一插入每条记录。

  4. 连接池大小应大于或等于工作线程数。

但是,使用 JDBC batch updates 效率更高。因此,您可以发送多个条目,以便将它们全部插入到一个批次中,而不是只向工作线程发送一个实体。

【讨论】:

  • 在插入之前,我必须验证并填充模型对象上的某些内容。我也想让它多线程。所以在运行内部我必须调用 processAcc(model) 和 processAcc(model) 在内部调用 .save。所以在这里 processAcc(model) 我的模型不能是最终的..现在该怎么办
  • 在处理阶段的同步块中做验证阶段,因为是并发环境。
【解决方案2】:

您需要一个单生产者多消费者线程安全队列。看看LMAX disruptor,最适合你。

LMAX Disruptor 是一个高性能的线程间消息传递库,它是Apache Storm 中工作线程内通信的默认消息传递系统@ 底层数据结构是一个无锁环形缓冲区。为了让它更快,它使用a lot of tricks to reduce false sharing

关注get started tutorial,有一个非常简单的例子可以参考。

【讨论】:

    猜你喜欢
    • 2021-11-30
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 2016-03-13
    • 2015-05-26
    • 1970-01-01
    相关资源
    最近更新 更多