Статический класс для получения соединений из пула соединений

Я хочу понять концепции пула соединений. Например, у меня есть следующий файл xml в META-INF с моими настройками БД.

 <Resource name="jdbc/appname"
              auth="Container"
              type="javax.sql.DataSource"
              maxActive="100" 
              maxIdle="30"
              maxWait="10000"
              minIdle="10"
              username="postgres" 
              password="123"
              driverClassName="org.postgresql.Driver"
              url="jdbc:postgresql://localhost:5432/Lab4"/>

Чтобы использовать пул соединений, я использую следующий класс

    public class DataBaseConnection {

        private static DataSource dataSource;

        static {
            try {
                InitialContext initContext = new InitialContext();
                dataSource = (DataSource) initContext.lookup("java:comp/env/jdbc/appname");
            } catch (NamingException ex) {
                throw new RuntimeException(ex);
            }
        }

        public static Connection getConnection() {
            try {
                return dataSource.getConnection();
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
        }

Это использование

public class UserQueries{ 
 public User selectUserByLoginAndPassword(final String login, final String password) {
        try(Connection connection=DataBaseConnection.getConnection())
        try (PreparedStatement st = connection.prepareStatement(SELECT_QUERY)) {
            st.setString(1, login);
            st.setString(2, password);
            ResultSet result = st.executeQuery();
            while (result.next()) {
                final User user = User.newBuilder()
                        .setId(result.getInt("id"))
                        .setAge(result.getInt("age"))
                        .setName(result.getString("name"))
                        .setPassword(result.getString("password"))
                        .setLogin(login)
                        .build();
                return user;

            }
        } catch (SQLException ex) {
            throw new RuntimeException(ex);
        }
        throw new NullPointerException("Nu such user in db");
    }

   }

Вопрос в том, если я изменю DataBaseConnection следующим образом:

public class DataBaseConnection {

        private  DataSource dataSource;

        public DataBaseConnection()
            try {
                InitialContext initContext = new InitialContext();
                dataSource = (DataSource) initContext.lookup("java:comp/env/jdbc/appname");
            } catch (NamingException ex) {
                throw new RuntimeException(ex);                
        }

        public  Connection getConnection() {
            try {
                return dataSource.getConnection();
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
        }

И я создам новый объект DataBaseConnection в каждом классе, использующем соединения БД, означает ли это, что каждый класс (например, UserQueries) будет создавать отдельный пул соединений для использования?

Пример

public class UserQueries{ 
  private DataBaseConnection dbCon = new DataBaseConnection();
 public User selectUserByLoginAndPassword(final String login, final String password) {
        try(Connection connection = dbCon.getConnection())
        try (PreparedStatement st = connection.prepareStatement(SELECT_QUERY)) {
            st.setString(1, login);
            st.setString(2, password);
            ResultSet result = st.executeQuery();
            while (result.next()) {
                final User user = User.newBuilder()
                        .setId(result.getInt("id"))
                        .setAge(result.getInt("age"))
                        .setName(result.getString("name"))
                        .setPassword(result.getString("password"))
                        .setLogin(login)
                        .build();
                return user;

            }
        } catch (SQLException ex) {
            throw new RuntimeException(ex);
        }
        throw new NullPointerException("Nu such user in db");
    }

   }

person Almas Abdrazak    schedule 20.10.2017    source источник


Ответы (1)


Каждый поиск JNDI возвращает новый экземпляр DataSource. Каждый экземпляр DataSource поддерживает собственный пул соединений.

См. реализацию tomcat Datasource.getConnection() ниже:,

public Connection getConnection() throws SQLException {
    if (pool == null)
        return createPool().getConnection();
    return pool.getConnection();
}

И это создает connectionPool:

private synchronized ConnectionPool pCreatePool() throws SQLException {
    if (pool != null) {
        return pool;
    } else {
        pool = new ConnectionPool(poolProperties);
        return pool;
    }
}

В итоге,

  • Новый экземпляр DataSource возвращается для каждого поиска JNDI.
  • Новый пул соединений будет создан для каждого экземпляра DataSource.
person inginia    schedule 20.10.2017
comment
Означает ли это, что использование статического источника данных гарантирует, что мое приложение будет использовать только один пул соединений? - person Almas Abdrazak; 20.10.2017
comment
Лучше сказать: рекомендуется использовать один экземпляр DataSource. ... мое приложение будет использовать только один пул соединений? -- Да. - person inginia; 20.10.2017