gpt4 book ai didi

java - JDBC 和线程

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:36:58 24 4
gpt4 key购买 nike

我有一个程序需要在给定的时间间隔内查询数据库,并使用它获取的记录调用执行一些操作,然后再次更新表。

我正在使用 ExecutorService 来运行线程,但我想知道,每个线程应该获得自己的连接(因为它需要更新数据库)还是我可以使用用于查询初始结果的相同连接?

连接池可以工作吗,我在 Oracle 9i 上。

最佳答案

您应该始终为单独的线程使用单独的连接,因为驱动程序在这种方式下不是线程安全的。连接池可以帮助您,因为它允许以安全的方式重用连接。

你也可以做一个查询调度模式 - 如果我理解你的问题 - 其中一个线程负责查询和启动可能更新数据库的 N 个线程 - 所有这些都有单独的连接对象。

您还可以考虑通过 PreparedStatement 进行批量更新,这样线程就不会在行锁和表锁方面相互绊倒,使用以下结构:

  • 1 个查询线程
  • NCPU 处理线程
  • 1个批量更新线程

就像一个迷你数据库 fork-join。

编辑

关于如何使用 Pstmt 进行批量更新的示例:

PreparedStatement pstmt = connection.prepareStatement(
"UPDATE table SET field=? WHERE id=?");
for (int i = 0; i < 100; i++) {
pstmt.setInt(1, i * i);
pstmt.setInt(2, i);
pstmt.addBatch();
}
pstmt.executeBatch();
pstmt.close();

或者您可以在更新请求从处理线程到达的循环中查询队列:

class WhatToUpdate {
public int id;
public int value;
}
Queue<WhatToUpdate> queue = new LinkedBlockingQueue<WhatToUpdate>();

PreparedStatement pstmt = connection.prepareStatement(
"UPDATE table SET field=? WHERE id=?");

int poisons = THE_NUMBER_OF_PROCESSING_THREADS;
while (true) {
WhatToUpdate record == queue.take();
if (record == null) { // poison pill
if (--poisons <= 0) {
break;
}
}
pstmt.setInt(1, record.value);
pstmt.setInt(2, record.id);
pstmt.addBatch();
}
pstmt.executeBatch();
pstmt.close();

关于java - JDBC 和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1215979/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com