Можно ли использовать статический экземпляр java.sql.Connection в многопоточной системе?

Я запускаю веб-приложение на Tomcat. У меня есть class, который обрабатывает все запросы БД. Этот class содержит объект Connection и методы, которые возвращают результаты запроса.

Это объект соединения:

 private static Connection conn = null; 

Он имеет только один экземпляр (singleton).

Кроме того, у меня есть методы, которые выполняют запросы, такие как поиск пользователя в db:

 public static ResultSet searchUser(String user, String pass) throws SQLException 

Этот метод использует статический объект Connection . Мой вопрос в том, является ли мое использование в статическом streamе объектов Connection безопасным? Или это может вызвать проблемы, когда многие пользователи searchUser метод searchUser ?

Мое использование в статичном streamе объектов Connection безопасно?

Точно нет!

Таким образом, соединение будет разделяться между всеми запросами, отправленными всеми пользователями, и, следовательно, все запросы будут мешать друг другу. Но threadsafety – это не единственная проблема, утечка ресурсов – это и ваша другая проблема. Вы сохраняете одно соединение открытым в течение всего срока службы приложения. Средняя firebase database будет восстанавливать соединение, если оно открыто слишком долго, обычно от 30 минут до 8 часов, в зависимости от конфигурации БД. Поэтому, если ваше веб-приложение работает дольше, соединение теряется, и вы больше не сможете выполнять запросы.

Эта проблема также применяется, когда эти ресурсы хранятся как static переменная экземпляра экземпляра classа, которая многократно используется повторно.

Вы должны всегда получать и закрывать соединение, инструкцию и набор результатов в кратчайшей возможной области , желательно внутри одного и try-with-resources же блока try-with-resources где вы выполняете запрос в соответствии с идиомой JDBC:

 public User find(String username, String password) throws SQLException { User user = null; try ( Connection connection = dataSource.getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT id, username, email FROM user WHERE username=? AND password=md5(?)"); ) { statement.setString(1, username); statement.setString(2, password); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { user = new User(); user.setId(resultSet.getLong("id")); user.setUsername(resultSet.getString("username")); user.setEmail(resultSet.getString("email")); } } } return user; } 

Обратите внимание: здесь вы не должны возвращать ResultSet . Если вы еще не на Java 7, используйте блок try-finally котором вы вручную закрываете закрывающиеся ресурсы в обратном порядке по мере их приобретения.

Если вы беспокоитесь о подключении производительности, вместо этого вы должны использовать пул соединений. Это встроено во многие серверы приложений Java EE, и даже такие брандмауны, как Tomcat, поддерживают его. Просто создайте источник данных JNDI на самом сервере и позвольте вашему webapp захватить его как DataSource . Это прозрачно уже пул соединений.

Смотрите также:

  • Как подключиться к базе данных JDBC / источнику данных в приложении на основе сервлета?
  • Когда мое приложение теряет связь, как мне его восстановить?
  • Я использую JDBC Connection Pooling?
  • Показать JDBC ResultSet в HTML на странице JSP с использованием шаблонов MVC и DAO
  • Учебное пособие DAO с JDBC

Если вы работаете только с запросами Select (запросы searchUser как только выбор данных), не будет проблем, кроме конфликтов streamов.

Насколько я знаю, Connection может обрабатывать только один запрос за раз, поэтому, используя один экземпляр, вы по существу сериализуете доступ к базе данных. Но это не обязательно означает, что всегда безопасно обращаться к такой базе данных в многопоточной среде. Там могут быть проблемы, если одновременный доступ чередуется.

Interesting Posts
Давайте будем гением компьютера.