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

时间:2013-02-08 03:09:02

标签: java database static database-connection

我在这里有一个基本问题 - 我正在使用名为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 个答案:

答案 0 :(得分:1)

您正在各种线程之间共享一个对象引用变量...有时,创建一个连接对象,在它关闭之前(并将其引用设置为null),另一个线程启动,创建另一个对象并且永远不会关闭旧对象一。因此,该连接仍然存在,并且在某些时候,将打开太多连接并且您的DBMS可能会崩溃,从而引发一些错误,例如“太多连接”。问题不是你的驱动器,而是你的代码。请注意,某些线程也可能会关闭由另一个线程创建的连接!

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

答案 1 :(得分:1)

JDBC不是线程安全的,因此您不应该并行使用多个线程中的一个Connection对象,无论它是否存储在静态字段中。一旦你这样做,一个线程可能会在其他线程的查询中发送它的查询,所以数据库将收到完整的垃圾,如果数据库不是坚如磐石,这个垃圾可能会破坏数据库