0

我正在从一个数据库表中提取数千行并插入到另一个数据库表中。我不想将所有记录加载到内存中,然后插入到另一个数据库中。

因此,我正在尝试使用 BlockingQueue 使用一个线程加载提取器结果,并使用另一个线程同时插入另一个数据库。我正在使用 Spring JdbcTemplate 来访问我的数据库。

这是我的计划

    public void performExtractionInsertion(JdbcTemplate inboundJdbcTemplate, JdbcTemplate outboundJdbcTemplate){

        final BlockingQueue queue = new LinkedBlockingQueue<Transaction>(50);
        ExecutorService executor = Executors.newFixedThreadPool(2);
        final String SELECT_QUERY = "SELECT acc_number, date, type  FROM transactions";
        final String INSERT_QUERY = "INSERT INTO analysis(col1, col2, col3) VALUES(?,?,?)";

        executor.execute(new Runnable() {
            @Override
            public void run() {
                    queue.put(/*IMPLEMENTATION OF EXTRACTOR USING inboundJdbcTemplate*/);
            }
        });
        executor.execute(new Runnable() {
            @Override
            public void run() {
                queue.take(/*IMPLEMENTATION OF INSERTER USING outboundJdbcTemplate*/)
            }
        });
}

有人可以告诉我如何实现 EXTRACTOR 和 INSERTER 以便他们使用相同的 BlockingQueue 来限制内存中的行数吗?

这是正确的方法吗?我还能使用 jdbcTemplate 吗?最智能、最方便的方法是什么?

多谢你们

顺便说一句,事务是要保存要插入的提取元素的对象的类。

4

1 回答 1

1

我遇到了同样的情况(在稍微不同的环境中)。我不是为了 JdbcTemplate,而是为了 MappingSQLQuery。我认为,至少对于查询它更适合我的需要。鉴于您愿意更改,代码可能如下所示

MappingSQLQuery selector = ...;       
executor.execute(new Runnable() {
  public void run() {
    List<WrapObject> list = selector.execute();
    for (WrapObject object : list) {
      while (!queue.offer(object)) {
        Thread.sleep(100);
      }
    }
    while (!queue.offer(WrapObject.NULL_OBJECT)) {
      Thread.sleep(100);
    }
  }
});
executor.execute(new Runnable() {
  public void run() {
    WrapObject object;
    while ((object = queue.take) != WrapObject.NULL_OBJECT) {
      outboundJdbcTemplate.update(INSERT_QUERY, object.getParam1(),...)
    }
  }
});

给定 WrapObject 的合适定义,这应该可以解决问题。

大量使用性能关键的 DB-Systems 我发现了以下两件事。

  1. 通常,重新实现 Spring 映射器可以让您更好地控制数据库发生的事情(尤其是批量更新、PreparedStatements 的编译时间、设置批量大小)

  2. 如果您看一下代码,您会了解到,与您相关的过度泛型 Spring-JDBC 类的部分大多是 10-20 行,并且可以轻松地针对您的特定情况重新实现,同时显着加快您的应用程序

  3. 根据您的数据库,您可能希望使用多个读取器/写入器。我曾与 Oracle-Clusters 合作过,其中八个并行读取进程甚至不会开始给硬件带来很大的负载

于 2013-05-09T19:17:55.570 回答