如何使用JPA和Hibernate使用多个处理线程来持久保存实体

时间:2015-02-05 07:07:12

标签: java multithreading spring hibernate transactions

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

我正在使用Spring和Hibernate。

在高级别我正在执行以下步骤:

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

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

  3. 验证,在oracle db中调用服务层,dao层和存储实体。

  4. 此流程使用for循环。因此,存在1比1的数据插入。

    现在我想在使用多线程时这样做。

    方法:

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

    2. 多个线程会将对象从队列中出列并从第3点开始。

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

2 个答案:

答案 0 :(得分: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. 连接池大小应大于或等于工作人员数。
  5. 然而,它是much more efficient to use JDBC batching。因此,您可以发送多个条目,而不是仅向工作线程发送一个实体,而是将它们全部插入到一个批处理中。

    查看this article for more details about enabling JDBC batch inserts in Hibernate

答案 1 :(得分:0)

您需要一个单生产者多用户线程安全队列。看看LMAX disruptor,这是最适合你的。

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

按照get started tutorial,您可以参考一个非常简单的示例。