Java并发查询同一表以进行电子邮件处理



我有一个MySQL表,该表充当电子邮件队列 - 保留所有需要发送的记录。我正在尝试使用多个线程执行每个电子邮件的发送。每个线程必须对此电子邮件队列表进行查询,以获取一组记录,然后将其从表中发送并删除。

您如何确定每个线程将从表中获取的记录?从那里,您如何管理这些并发查询?我正在使用Hibernate的Java Spring Boot。

我会想象下面的东西。这是使用数据库中的一行ID完成的。如果您有巨大的ID差距,那不是一个好的解决方案。您可以对此进行重构以使用某些日期列或任何其他可能有助于批量记录的数据。

10-线程数

i-当前线程的数量我们正在通过

迭代

10000-批量大小,用于获取10000封电子邮件的批次

counter-变量要知道哪个线程应负责哪个ID批次

maximumEmailId-电子邮件表中的电子邮件的最大ID

1. Create 10 numbered threads - 0, 1, 2..., 9
2. Start every thread
3. For each thread number (i):
4. For counter = 0, step 10000
5. if (counter / 10000) % 10 == i then
- SELECT * FROM emails WHERE id BETWEEN (counter) AND (counter + 10000)
- Send emails
6. if counter > maximumEmailId then break;

它的行为会这样:

iteration 0:
  -thread 0 - counter = 0 - select ... where id between 0 and 10000
  -thread 1 - counter = 10000 - select ... where id between 10000 and 20000
  -thread 9 - counter = 90000 - select ... where id between 90000 and 100000
iteration 1:
  -thread 0 - counter = 100000 - select ... where id between 100000 and 11000
  -thread 1 - counter = 110000 - select ... where id between 110000 and 12000
  -thread 9 - counter = 190000 - select ... where id between 190000 and 20000

基本上,此解决方案与锁定,技术并发技巧等无关,您只需将数据集划分,因此没有人试图读取同一批次。试想一下地面上的100个盒子,线程0取编号的0, 10, 20,...,90,线程11, 11, 21,...,91等。

最新更新