Java “共享jdbc”;“连接”;跨线程
我有一个定期运行的主线程。它使用setAutoCommit(false)打开一个连接,并作为引用传递给几个子线程以执行各种数据库读/写操作。在子线程中执行了相当多的操作。在所有子线程完成其db操作后,主线程使用打开的连接提交事务。请注意,我在Executor服务中运行线程。我的问题是,是否建议跨线程共享连接?如果“是”,请查看下面的代码是否正确地实现了它。如果“否”,在多线程场景中执行事务的其他方式是什么?欢迎评论/建议/新想法。伪代码Java “共享jdbc”;“连接”;跨线程,java,multithreading,jdbc,transactions,Java,Multithreading,Jdbc,Transactions,我有一个定期运行的主线程。它使用setAutoCommit(false)打开一个连接,并作为引用传递给几个子线程以执行各种数据库读/写操作。在子线程中执行了相当多的操作。在所有子线程完成其db操作后,主线程使用打开的连接提交事务。请注意,我在Executor服务中运行线程。我的问题是,是否建议跨线程共享连接?如果“是”,请查看下面的代码是否正确地实现了它。如果“否”,在多线程场景中执行事务的其他方式是什么?欢迎评论/建议/新想法。伪代码 Connection con = getPrimaryDa
Connection con = getPrimaryDatabaseConnection();
// let me decide whether to commit or rollback
con.setAutoCommit(false);
ExecutorService executorService = getExecutor();
// connection is sent as param to the class constructor/set-method
// the jobs uses the provided connection to do the db operation
Callable jobs[] = getJobs(con);
List futures = new ArrayList();
// note: generics are not mentioned just to keep this simple
for(Callable job:jobs) {
futures.add(executorService.submit(job));
}
executorService.shutdown();
// wait till the jobs complete
while (!executorService.isTerminated()) {
;
}
List result = ...;
for (Future future : futures) {
try {
results.add(future.get());
} catch (InterruptedException e) {
try {
// a jobs has failed, we will rollback the transaction and throw exception
connection.rollback();
result = null;
throw SomeException();
} catch(Exception e) {
// exception
} finally {
try {
connection.close();
} catch(Exception e) {//nothing to do}
}
}
}
// all the jobs completed successfully!
try {
// some other checks
connection.commit();
return results;
} finally {
try {
connection.close();
} catch(Exception e){//nothing to do}
}
您可以创建一个代理类来保存JDBC连接并提供同步访问 去吧。线程不应直接访问连接 根据您提供的使用和操作,您可以使用
synchronized
方法,或者在代理需要锁定直到其离开特定状态时锁定对象
对于那些不熟悉代理设计模式的人。给你。基本思想是代理实例隐藏另一个对象,但提供相同的功能。我不建议您在线程之间共享连接,因为使用连接的操作非常缓慢,并且应用程序的整体性能可能会受到影响
<> >我建议您使用并提供单独的连接到每个线程。 在这种情况下,考虑为每个工作人员创建一个单独的连接。如果任何一个工作进程出现故障,请回滚所有连接。如果全部通过,则提交所有连接
如果您将有数百个工作线程,那么您需要提供对连接对象的同步访问,或者按照@mike和@NKukhar的建议使用连接池。连接对象不是线程安全的,与多个线程共享它可能会导致问题这里有问题吗?如果您想查看代码,请发到,请您再详细说明一下好吗?看起来,虽然连接在技术上是线程安全的,但您仍然不想在线程之间传递它:我忘了提到我的问题中的一点,仅供参考,此模块在Jboss-5内部运行,ServletContextListener在那里启动主调度程序线程,重要的是,主线程从配置的数据源池获取连接。如果可以使用连接池,如何维护事务、仅在所有子线程成功结束时成功的事务或事务回滚?每个线程都从连接池中获取连接?那么,您可以将从连接池中检索到的连接保存在某个共享集合中,并在线程完成执行后对其执行任何操作。但这是一种非常糟糕的交易管理方式。例如,我更喜欢使用spring事务管理器。但请注意,它不支持事务。相反,每个工作线程都会获取数据,对其进行操作并将其插入到数据库中,我希望更改工作线程以将其所有已处理的数据返回到主线程,这样,如果我正确地接收到了它们的所有对象,我将在单个连接中更新数据库中的所有内容,我从池中获取的连接。我也有这个想法,但同步执行是我唯一担心的,所以我没有尝试。