【问题标题】:Reading different sets of data from same DB table by various java threads通过各种java线程从同一个数据库表中读取不同的数据集
【发布时间】:2016-06-27 18:14:44
【问题描述】:

我的问题与this old SO question 非常相似,并且没有发布令人满意的答案。

在 DB2 中有一个 DB 表,我正在尝试通过两个或多个单独的 Java 线程进行并行记录读取,前提是这些线程应该读取不同的数据集,即如果 THREAD-1 已读取前 1000 条记录,则 THREADS-2不应该选择那些记录,但如果可用的话,应该选择不同的 1000 条记录。

由于线程将读取不同的行,因此在读取时不会发生冲突。连接对象也不会在线程之间共享——它们将使用自己的数据库连接。

数据库是 DB2,并且该表已经在其中一列上进行了范围分区。

线程数不是固定的,而是可配置的,因此我们可以在更强大的机器上运行更多线程。

有什么策略可以将阅读器线程限制在表格的特定区域而不是相互踩踏,即如何在逻辑上划分表格以便线程继续阅读不同的区域? Java 进程可以利用 DB2 范围分区吗?

一种解决方案是将不同范围的主键移交给这些线程,但为此我必须在启动时读取整个表,并且我试图避免这样做。

【问题讨论】:

  • 主键的本质是什么?
  • 三列 - 两个整数和一个 varchar。表仅在主键的 varchar 列上进行范围分区。

标签: java multithreading jdbc db2


【解决方案1】:

一种方法是选择数据的一部分。假设您的密钥是一个数字(或数字是您的密钥的一部分),您可以在 WHERE 条件下使用模函数 (mod) - 这对于可配置的线程数量来说足够灵活。

SELECT... FROM... WHERE mod(key, 3) = 0 

三个线程中的第一个线程,第二个线程 mod(key, 3) = 1,依此类推。

如果您真的关注分区,则必须首先查询 DB2 系统目录以检索表的分区信息 (SYSCAT.DATAPARTITIONS)

【讨论】:

  • 谢谢,数字列是主键列之一。主键由三列组成 - 两个数字和一个 varchar,varchar 列是对表进行分区的列。
  • 我确实尝试了各种方法,看起来只通过线程的 WHERE 子句限制读取数据是唯一可行的选择。
  • 在我的情况下,当线程拾取数据时,向表中添加新列以指示进度的另一个选项不是一个选项。此选项也不会有良好的性能,因为更新行将是额外的负担。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2015-05-26
相关资源
最近更新 更多