Java “共享jdbc”;“连接”;跨线程

Java “共享jdbc”;“连接”;跨线程,java,multithreading,jdbc,transactions,Java,Multithreading,Jdbc,Transactions,我有一个定期运行的主线程。它使用setAutoCommit(false)打开一个连接,并作为引用传递给几个子线程以执行各种数据库读/写操作。在子线程中执行了相当多的操作。在所有子线程完成其db操作后,主线程使用打开的连接提交事务。请注意,我在Executor服务中运行线程。我的问题是,是否建议跨线程共享连接?如果“是”,请查看下面的代码是否正确地实现了它。如果“否”,在多线程场景中执行事务的其他方式是什么?欢迎评论/建议/新想法。伪代码 Connection con = getPrimaryDa

我有一个定期运行的主线程。它使用setAutoCommit(false)打开一个连接,并作为引用传递给几个子线程以执行各种数据库读/写操作。在子线程中执行了相当多的操作。在所有子线程完成其db操作后,主线程使用打开的连接提交事务。请注意,我在Executor服务中运行线程。我的问题是,是否建议跨线程共享连接?如果“是”,请查看下面的代码是否正确地实现了它。如果“否”,在多线程场景中执行事务的其他方式是什么?欢迎评论/建议/新想法。伪代码

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事务管理器。但请注意,它不支持事务。相反,每个工作线程都会获取数据,对其进行操作并将其插入到数据库中,我希望更改工作线程以将其所有已处理的数据返回到主线程,这样,如果我正确地接收到了它们的所有对象,我将在单个连接中更新数据库中的所有内容,我从池中获取的连接。我也有这个想法,但同步执行是我唯一担心的,所以我没有尝试。