2011-10-10 2 views
1

J'ai essayé de mettre à jour mon code ojdbc de ojdbc14-10.2.0.1.0 à ojdbc6-11.1.0.7.0. Nous avons utilisé OracleConnectionCacheImpl pour les connexions de sources de données, puis nous sommes passés au pool de connexions universelles en utilisant OracleDataSource au cœur. Voici comment nous avons configuré il au printemps:Gestion de la mémoire du pool de connexions universelles

<bean id="myDatasource" class="oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource"> 
     <property name="URL" value="@[email protected]"/> 
     <property name="user" value="@[email protected]"/> 
     <property name="password" value="@[email protected]"/> 
     <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/> 
     <property name="connectionPoolName" value="MFR_RTE_POOL"/> 
     <property name="minPoolSize" value="5"/> 
     <property name="maxPoolSize" value="100"/> 
     <property name="validateConnectionOnBorrow" value="true" /> 
     <property name="connectionWaitTimeout" value="30"/> 
     <property name="connectionHarvestMaxCount" value="25"/> 
     <property name="connectionHarvestTriggerCount" value="5"/> 
     <property name="maxStatements" value="100"/> 
</bean> 

Il a fallu un peu pour le faire fonctionner sans erreurs de connexion fermées, mais maintenant j'ai un problème avec la gestion de la mémoire. J'ai couru jconsole contre une application que j'ai qui utilise un ThreadPool. Cette application utilise un pool de threads et utilise ThreadPoolExecutors pour créer des demandes de frais basées sur les données transmises à partir du fichier. Un fichier peut contenir des centaines de milliers de demandes de frais. Mon problème est que la mémoire à long terme dans le tas se remplit et ne libère pas d'objets. Dans le test de performance que j'ai mis en place, la mémoire à long terme dans Garbage Collection se remplit dans environ 20-25 minutes et ne libère jamais. L'application finit par atteindre l'exception GC Limit Exceeded et se bloque.

Lorsque j'exécute le même test avec l'ancienne classe OracleConnectionCacheImpl, il fonctionne sans problème. Le pool de threads et tout le code qui l'accompagne ont été écrits pour s'exécuter en utilisant des versions plus anciennes de Spring (1.2.6) et d'anciens pilotes ojdbc, mais y a-t-il vraiment une différence de fonctionnement entre OracleConnectionCacheImpl et Universal Connection Pooling? Est-ce que je cherche à réécrire mon modèle de domaine si je veux adapter aux dernières versions du code du pilote JDBC d'Oracle. J'ai essayé la connexion OracleDataSource et il a lamentablement échoué avec NullPointerExceptions après avoir travaillé simultanément sur plusieurs fichiers. Je suis ensuite allé à UCP (à la suggestion d'un autre poste dans ce forum) qui fonctionne bien dans toutes les applications sauf une. À ce stade, j'essaie de déterminer si je peux optimiser davantage le bean Spring config pour ma source de données ou dois-je commencer à penser à la mise à niveau de la base de code. Comme indiqué précédemment, ce code fonctionne très bien par rapport à l'ancienne classe ojdbc, mais j'ai rencontré des problèmes à chaque étape de la mise en œuvre d'UCP. Je commence à me demander si cela vaut même la peine d'être amélioré.

Répondre

6

Ce problème m'a mis sur écoute pendant des mois, je l'espère, ce que je suis venu avec aide quelqu'un d'autre là-bas:

J'ai finalement trouver une solution à mon problème. Au lieu d'utiliser OracleDataSource comme l'usine de connexion:

<property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/> 

Je suggère d'essayer OracleConnectionPoolDataSource:

<property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleConnectionPoolDataSource"/> 

OracleConnectionPoolDataSource étend OracleDataSource et semble faire mieux dans les applications où plusieurs connexions doivent être ouverts par de multiples ressources. Dans mon cas, j'ai une application qui nécessite le traitement de plusieurs fichiers batch. Le même code SQL est exécuté encore et encore, mais l'application a besoin d'une nouvelle connexion pour chaque nouveau fichier. Dans ces circonstances, OracleDataSource a souvent échoué à des erreurs de connexion (SQLException: connexion fermée, NullPointerException: connexion fermée avec ou sans UCP), entraînant des problèmes de récupération de place (le GC à long terme se remplirait et le GC échouerait). peu importe combien de mémoire j'ai ajouté à la JVM). J'ai trouvé OracleDataSource pour bien fonctionner sur les applications qui n'utilisent pas beaucoup de traitement par lots. Par exemple, une autre application que j'utilise est une application de traitement de fichiers, mais elle ne fonctionne que sur un fichier à la fois. OracleDataSource fonctionne très bien dans cette circonstance. Cela semble également bien fonctionner pour les applications Web. Nous avons une application Web nous avons installé OracleDataSource il y a 9 mois et n'a eu aucun problème.

Je suis sûr qu'il existe des moyens de faire fonctionner OracleDataSource ainsi que OracleConnectionPoolDataSource, mais cela fonctionne pour moi.

Questions connexes