2015-06-15 2 views
-1

Я использую следующий код для подключения к базе данных для моего простого проекта входа в систему jsp/servlet, т. Е. Singleton. Когда я вхожу в систему для времени frist, он работает после успешного выхода из системы. Теперь проблема начинается, когда я снова пытаюсь сделать ошибку входа в систему, сказав: «Сильное: сообщение об ошибке: после закрытия соединения никаких действий не разрешено». Но когда я удаляю соединение с закрытием кода, он снова работает нормально. Пожалуйста, предложите мне использовать его или избегать.Синглтон применим в проекте сервлета/jsp?

public class ConnectionMgr { 

    private static ConnectionMgr instance = null; 

    private static final String USERNAME = "root"; 
    private static final String PASSWORD = ""; 
    private static final String M_CONN_STRING = "jdbc:mysql://localhost:3306/generator"; 
    private static final String H_CONN_STRING = "jdbc:hsqldb:data/generator"; 

    private DBType dbType = DBType.MYSQL; 

    private Connection conn = null; 


    private ConnectionMgr() { 
    } 

    public static ConnectionMgr getInstance() { 
     if (instance == null) { 
      instance = new ConnectionMgr(); 
     } 
     return instance; 
    } 

    public void setDBType(DBType dbType) { 
     this.dbType = dbType; 
    } 

    private boolean openConnection() { 
     try { 
      switch (dbType) { 

       case MYSQL: 
        Class.forName("com.mysql.jdbc.Driver"); 
        conn = DriverManager.getConnection(M_CONN_STRING, USERNAME, PASSWORD); 
        return true; 

       case HSQL: 
        conn = DriverManager.getConnection(H_CONN_STRING, USERNAME, PASSWORD); 
        return true; 

       default: 
        return false; 
      } 
     } catch (SQLException | ClassNotFoundException e) { 
      System.err.println(e); 
      DBUtil.processException((SQLException) e); 
      return false; 
     } 
    } 

    public Connection getConnection() { 
     if (conn == null) { 
      if (openConnection()) { 
       System.out.println("Connection opened"); 
       return conn; 
      } else { 
       return null; 
      } 
     } 
     return conn; 
    } 

    public void processException(SQLException e) { 
     System.err.println("Silgleton connection()Error -->"); 
     System.err.println("Erroe message:" + e.getMessage()); 
     System.err.println("Error code:" + e.getErrorCode()); 
     System.err.println("Error State:" + e.getSQLState()); 
    } 

    public void close() { 
     System.out.println("Closing connection"); 
     try { 
      conn.close(); 
      conn = null; 
     } catch (Exception e) { 
     } 
    } 
} 
+0

Одна из критических замечаний, которые я имею против одиночных игроков, заключается в том, что они приводят к таким же проблемам, что и срок жизни содержащегося объекта становится неизвестным, если он не предназначен для приложения. При выполнении любого доступа к базе данных с веб-сервера вам, вероятно, потребуется несколько подключений к базе данных для обработки параллельных запросов. Вот почему используются RDBMSes - они позволяют вам делать именно это. Поскольку клиентскому коду разрешено закрывать соединение, Singleton эффективно теряет контроль, а последующий код нарушает его. –

+0

Кроме того, вы должны использовать новые подключения для каждой транзакции БД и немедленно закрывать их; Таким образом, вы можете установить контроль доступа, отключить автоматическую фиксацию (для нескольких запросов в одной транзакции) по мере необходимости, отменить транзакцию, если произошла ошибка, и обеспечить разумные атомные обновления, среди других тонкостей. Путем повторного использования соединения без надлежащего управления своим состоянием вы открываете двери для всех видов проблем по дороге. –

ответ

1

Ваш менеджер соединений не является потокобезопасным. Поэтому, пока один пользователь пытается прочитать данные с использованием одного экземпляра, поток другого пользователя может завершить закрытое соединение.

Вместо этого используйте что-то вроде Apache DBCP, которое также даст вам пул соединений.

Если вы все еще хотите использовать приведенный выше код, измените его как диспетчер соединений как обычный объект, а не как одиночный.

+0

Благодарю вас за помощь. – user3811169

0

Возможно, вы сохраняете ссылку на экземпляр «соединения» первого запроса, а затем повторно используете эту ссылку для своего второго запроса.

Попробуйте сделать вывод, что вы вызываете getConnection() каждый раз, когда к сервлету приходит новый запрос.

Внесите System.out.println("your-method-name-") во все методы вашего класса ConnectionMgr.

+0

thankx много сэр, теперь я понимаю, что, если я использую тот же код для настольного приложения? – user3811169

 Смежные вопросы

  • Нет связанных вопросов^_^