Автор оригинала: Vlad Mihalcea.
Oracle Express Edition – это бесплатная версия Oracle Enterprise Edition, и ее меньший размер делает ее очень удобной для тестирования различных функций Oracle.
Согласно документации Oracle , Express Edition может использовать не более одного процессора и 1 ГБ оперативной памяти, но на самом деле существуют и другие ограничения, которые не всегда очевидны.
Следующий тест пытается имитировать среду транзакций с низкой задержкой, поэтому соединение арендуется на очень короткий промежуток времени:
private void simulateLowLatencyTransactions( DataSource dataSource, int waitMillis) throws SQLException { for (int i = 0; i < callCount; i++) { try { try (Connection connection = dataSource.getConnection()) { //Let's assume we are running a //short-lived transaction sleep(waitMillis); } } catch (SQLException e) { LOGGER.error("Exception on iteration " + i, e); } } }
Этот тест работает нормально до тех пор, пока время ожидания не превысит определенное пороговое значение, и в этом случае база данных периодически начинает выдавать следующее исключение:
ERROR [main]: c.v.b.h.j.c.OracleConnectionCallTest - Exception on iteration 111 java.sql.SQLException: Listener refused the connection with the following error: ORA-12516, TNS:listener could not find available handler with matching protocol stack at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:489) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:553) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at oracle.jdbc.driver.T4CConnection. (T4CConnection.java:254) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:528) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:280) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:207) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:157) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at com.vladmihalcea.book.high_performance_java_persistence.jdbc.connection.OracleConnectionCallTest.simulateLowLatencyTransactions(OracleConnectionCallTest.java:50) [test-classes/:na] at com.vladmihalcea.book.high_performance_java_persistence.jdbc.connection.OracleConnectionCallTest.testConnections(OracleConnectionCallTest.java:40) [test-classes/:na]
Хотя код однопоточный, Oracle начинает жаловаться, что прослушиватель запросов на подключение не может найти обработчик процесса для обслуживания входящего запроса.
Это предположение можно доказать, подняв процессы и сеансы параметры с более высоким значением:
alter system set processes=1000 scope=spfile; alter system set sessions=1000 scope=spfile;
С этими новыми настройками код работает нормально, и никаких исключений не выдается. Хотя увеличение ограничений процессов и сеансов устраняет проблему, это решение является лишь обходным путем, и оно только повышает порог подключения вместо устранения основной причины.
Одно из возможных объяснений приводится в этом Примечании по устранению неполадок IBM , предполагающем, что прослушиватель соединений может не получать мгновенное уведомление о событиях закрытия соединения. Это может привести к тому, что прослушиватель подключений ошибочно подтвердит фактическое количество подключений и предположит, что максимальное количество процессов уже достигнуто.
В Oracle 11g Enterprise Edition эта проблема не поддается повторению.
Проницательные читатели заметят проблему при просмотре трассировки стека исключений. OracleDataSource не предлагает никакого механизма объединения соединений и это приводит к большим накладным расходам на установление соединения как на драйвере, так и на стороне сервера.
Использование пула соединений устраняет эту проблему, поскольку соединения используются повторно, а не устанавливаются по требованию. Пул соединений значительно сокращает время получения соединения, что также приводит к снижению задержек транзакций и повышению пропускной способности.