Вступление
Oracle Express Edition — это бесплатная версия Oracle Enterprise Edition, а ее меньший размер делает ее очень удобной для тестирования различных функций Oracle.
Согласно документации Oracle , Express Edition может использовать не более одного ЦП и 1 ГБ ОЗУ, но в действительности существуют другие ограничения, которые не всегда очевидны.
Аномалия обработки соединения с базой данных
Следующие тесты пытаются смоделировать среду транзакций с низкой задержкой, поэтому соединение арендуется на очень короткий промежуток времени:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
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); } } } |
Этот тест работает нормально до тех пор, пока время ожидания не превысит определенного порогового значения, и в этом случае база данных время от времени начинает выдавать следующее исключение:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
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.<init>(PhysicalConnection.java:553) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0] at oracle.jdbc.driver.T4CConnection.<init>(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 начинает жаловаться на то, что прослушиватель запросов на подключение не может найти обработчик процесса для обслуживания входящего запроса.
Это предположение можно подтвердить, повысив параметры процессов и сеансов до более высокого значения:
1
2
|
alter system set processes= 1000 scope=spfile; alter system set sessions= 1000 scope=spfile; |
С этими новыми настройками код работает нормально и исключений не выдается. Хотя увеличение лимитов процессов и сеансов устраняет проблему, это решение является лишь обходным путем и повышает порог подключения, а не устраняет основную причину.
Это возможное объяснение дано в этой заметке IBM по устранению неполадок , в которой говорится, что прослушиватель соединения не может быть немедленно уведомлен событиями закрытия соединения. Это может привести к тому, что прослушиватель соединений неверно установит фактический счетчик соединений и предположит, что максимальное число процессов уже достигнуто.
В Oracle 11g Enterprise Edition эта проблема не воспроизводится.
Исправление
Проницательные читатели заметят проблему, глядя на трассировку стека исключений. OracleDataSource не предлагает какого-либо механизма пула соединений, и это приводит к большим накладным расходам на установление соединения как на драйвере, так и на стороне сервера.
Использование пула соединений устраняет эту проблему, поскольку соединения используются повторно, а не устанавливаются по требованию. Пул соединений значительно сокращает время установления соединения, что также приводит к снижению задержек транзакций и повышению пропускной способности.
Ссылка: | Почему вы всегда должны использовать пул соединений с Oracle XE от нашего партнера JCG Влада Михалча в блоге Влада Михалча . |