Lors du test du mécanisme d'établissement de connexion Oracle XE, j'ai rencontré le problème suivant. Bien que les connexions soient fermées à chaque itération, après 50 à 100 connexions, Oracle commence à lancer par intermittence l'exception suivante:
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.test(OracleConnectionCallTest.Java:57) [test-classes/:na]
Le test peut être trouvé sur GitHub :
for (int i = 0; i < callCount; i++) {
try {
long startNanos = System.nanoTime();
try (Connection connection = dataSource.getConnection()) {
}
timer.update(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
sleep(waitMillis);
} catch (SQLException e) {
LOGGER.info("Exception on iteration " + i, e);
}
}
Si j'essaie d'ouvrir/fermer des connexions avec une étape d'attente de 35 ms, tout fonctionne bien. Si je baisse l'attente à 10 ms, l'exception commence à être levée de temps en temps.
Une raison possible pourrait être expliquée par cet article: http://www-01.ibm.com/support/docview.wss?uid=swg21603472
L'une des raisons les plus courantes pour lesquelles les erreurs TNS-12516 et/ou TNS-12519 sont signalées est que le nombre maximal configuré de PROCESSUS et/ou de SESSIONS est atteint. Lorsque cela se produit, les gestionnaires de service pour l'écouteur TNS deviennent "bloqués" et aucune nouvelle connexion ne peut être établie. Une fois que l'écouteur TNS reçoit une mise à jour du processus PMON associé à l'instance de base de données indiquant à l'écouteur TNS que les seuils sont inférieurs à la limite configurée, et la base de données accepte maintenant les connexions, la connectivité reprend.
- PMON est responsable de la mise à jour de l'écouteur avec des informations sur une instance particulière, telles que les informations de chargement et de répartition. La charge maximale pour les connexions dédiées est déterminée par le paramètre PROCESSES. La fréquence à laquelle PMON fournit des informations SERVICE_UPDATE varie en fonction de la charge de travail de l'instance. L'intervalle maximal entre ces mises à jour de service est de 10 minutes.
- L'écouteur compte le nombre de connexions qu'il a établies avec l'instance mais n'obtient pas immédiatement d'informations sur les connexions qui se sont terminées. Ce n'est que lorsque PMON met à jour l'auditeur via SERVICE_UPDATE que l'auditeur est informé de la charge actuelle. Comme cela peut prendre jusqu'à 10 minutes, il peut y avoir une différence entre la charge d'instance actuelle selon l'écouteur et la charge d'instance réelle.
Lorsque l'auditeur pense que le nombre actuel de connexions a atteint la charge maximale, il peut définir l'état du gestionnaire de services pour une instance sur "bloqué" et commencer à refuser les connexions clientes entrantes avec l'une des erreurs suivantes: ora-12519 ou ora-1251 "
Je voulais savoir s'il s'agit d'une sorte de bogue ou si c'est simplement la façon dont Oracle est conçu pour fonctionner.
Sur Oracle 11g Enterprise Edition, cela fonctionne très bien, c'est donc une limitation XE.
tiliser le pool de connexions est probablement le meilleur moyen de résoudre ce problème, ce qui réduit également le temps d'acquisition de la connexion et augmente les pics de trafic.
Ce n'est pas un bug. Ce comportement est attendu. Si vous devez augmenter les connexions, modifiez simplement la limite de processus:
SQL> show parameter processes
processes integer 150
SQL> alter system set processes = <integer> scope=[...];
SQL> shutdown immediate;
SQL> startup;
- Soit en utilisant pfile ou spfile, vous devrez rebondir la base de données, car le paramètre de processus est statique.
Et par souci d'exhaustivité, il vaut la peine de dire que dans un environnement de production et que vous devez augmenter la limite des processus, vous devrez peut-être également augmenter les paramètres corrélés, tels que les transactions et les sessions (dérivées des processus). Vous pouvez interroger v $ resource_limit pour déterminer les limites et valeurs actuelles utilisées:
SQL> select * from v$resource_limit where resource_name in ('processes', 'sessions', 'transactions');