有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java数据库在使用静态连接时挂起

我这里有一个基本问题——我正在使用一个名为XpressMP的新数据库

我编写了一个多线程程序,将大量记录插入数据库。在连接数据库时,我注意到一件最重要的事情:

在我的程序中,如果我使用下面的内容-

class Task implements Runnable {

   private Connection dbConnection = null;
   private PreparedStatement preparedStatement = null;

   //other stuff

 @Override
  public void run() {

   try {

      dbConnection = getDBConnection();

   } finally {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
                preparedStatement = null;
            } catch (SQLException e) {
            }
        }
        if (dbConnection != null) {
            try {
                dbConnection.close();
                dbConnection = null;
            } catch (SQLException e) {
            }
        }
    }
  }
}

它工作正常,我正在关闭最后一个区块中的每个连接。我可以在数据库中插入更多的行

但是一旦我开始有意地(我不应该这么做)使用多线程的静态连接-

class Task implements Runnable {

   private static Connection dbConnection = null;
   private static PreparedStatement preparedStatement = null;

   //other stuff

 @Override
  public void run() {

  try {

    dbConnection = getDBConnection();

   } finally {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
                preparedStatement = null;
            } catch (SQLException e) {

            }
        }
        if (dbConnection != null) {
            try {
                dbConnection.close();
                dbConnection = null;
            } catch (SQLException e) {
            }
        }
    }
  }
}

整个数据库挂起在重新启动数据库之前,我无法使用该数据库。这意味着我的JDBC驱动程序有一些问题。我已经把这个问题告诉了DBA,他们正在与拥有该数据库的人员交谈

但我的问题是为什么它会挂起来。为什么


共 (2) 个答案

  1. # 1 楼答案

    您正在不同线程之间共享一个对象引用变量。。。有时,一个连接对象被创建,在它被关闭(其引用被设置为null)之前,另一个线程启动,创建另一个对象,并且从不关闭旧的对象。所以,那个连接仍然是活动的,在某个时间点,太多的连接将被打开,你们的DBMS可能崩溃,抛出一些错误,比如“太多连接”。问题不在于驱动器,而在于代码。请注意,某些线程也可能关闭由另一个线程创建的连接

    我认为您没有看到正在抛出的异常,因为您的外部try中没有catch。尝试创建连接时将引发异常。尝试在那里放置一个捕捉器以显示堆栈跟踪。如果您的数据库检测到此问题,它将工作(可能工作)

  2. # 2 楼答案

    JDBC不是线程安全的,所以您不应该并行使用来自多个线程的一个连接对象,不管它是否存储在静态字段中。一旦这样做,有可能一个线程将在其他线程的查询中间发送它的查询,因此数据库将接收完整的垃圾,如果数据库不可靠,则该垃圾可能会破坏数据库。p>