Après le redémarrage du serveur, la connexion Oracle du serveur Tomcat expire toutes les nuits. Avant le redémarrage, la connexion n'avait pas expiré. Aujourd'hui, dans la matinée, l'application génère une erreur de connexion JDBC lors de l'accès à la base de données. Redémarrer Tomcat corrige le problème. Je suppose que cela est dû au rétablissement des liens. Je pense que cela est dû au temps imparti par la base de données Oracle à la session. Comment désactiver le délai de session dans Oracle 11g?
Merci!
Steve
Config.groovy avec dev et test omis.
dataSource {
pooled = true
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
production {
dataSource {
driverClassName = "Oracle.jdbc.driver.OracleDriver"
username = "XXXXX"
password = "XXXXXX"
dialect = "org.hibernate.dialect.Oracle10gDialect"
dbCreate = "update" // one of 'create', 'create-drop','update'
url = "jdbc:Oracle:thin:@XXXXXX:1521:xxxx"
}
} }
C'est généralement contrôlé par le profil associé à l'utilisateur Tomcat se connecte en tant que.
SQL> SELECT PROFILE, LIMIT FROM DBA_PROFILES WHERE RESOURCE_NAME = 'IDLE_TIME';
PROFILE LIMIT
------------------------------ ----------------------------------------
DEFAULT UNLIMITED
SQL> SELECT PROFILE FROM DBA_USERS WHERE USERNAME = USER;
PROFILE
------------------------------
DEFAULT
Ainsi, l'utilisateur auquel je suis connecté a un temps d'inactivité illimité - pas de temps mort.
Adam a déjà suggéré des profils de base de données.
Vous pouvez vérifier le fichier SQLNET.ORA. Il existe un paramètre EXPIRE_TIME , mais il permet de détecter les connexions perdues, plutôt que de mettre fin aux connexions existantes.
Étant donné que cela se produit du jour au lendemain, cela ressemble davantage à un délai d'inactivité, qui pourrait être dû à un pare-feu entre le serveur d'applications et le serveur de base de données. La définition de EXPIRE_TIME may peut empêcher cela de se produire (car une vérification est effectuée toutes les 10 minutes pour vérifier que le client est actif).
Ou peut-être que la base de données est en train d'être arrêtée et redémarrée et que cela tue les connexions.
Sinon, vous devriez pouvoir configurer Tomcat avec un validationQuery afin qu'il redémarre automatiquement la connexion sans redémarrage de Tomcat.
Cela est probablement dû au pool de connexions de votre application. pas un problème de SGBD Oracle. La plupart des pools de connexions ont une instruction de validation qui peut s'exécuter avant de vous donner la connexion. Dans Oracle, vous voudriez "Sélectionnez 1 parmi deux".
La raison pour laquelle cela a commencé après le redémarrage du serveur est que le pool de connexions a probablement été ajouté sans redémarrage et que vous utilisez actuellement le pool de connexions pour la première fois. Quelles sont les dates de modification de vos fichiers de ressources traitant des connexions de base de données?
Valider un exemple de requête:
<Resource name="jdbc/EmployeeDB" auth="Container"
validationQuery="Select 1 from dual" type="javax.sql.DataSource" username="dbusername" password="dbpassword"
driverClassName="org.hsql.jdbcDriver" url="jdbc:HypersonicSQL:database"
maxActive="8" maxIdle="4"/>
EDIT: Dans le cas de Grails, il existe des options de configuration similaires pour le pool de Grails. Exemple pour Grails 1.2 (voir les notes de version pour Grails 1.2 )
dataSource {
pooled = true
dbCreate = "update"
url = "jdbc:mysql://localhost/yourDB"
driverClassName = "com.mysql.jdbc.Driver"
username = "yourUser"
password = "yourPassword"
properties {
maxActive = 50
maxIdle = 25
minIdle = 5
initialSize = 5
minEvictableIdleTimeMillis = 60000
timeBetweenEvictionRunsMillis = 60000
maxWait = 10000
}
}
Je suis arrivé à cette question en cherchant un moyen d'activer l'expiration du pool de sessions Oracle en fonction de la durée de vie totale de la session au lieu du temps d'inactivité . Un autre objectif est d'éviter la fermeture forcée des applications.
Il semble que cela soit possible en définissant pool requête de validation à
select 1 from V$SESSION
where AUDSID = userenv('SESSIONID') and sysdate-LOGON_TIME < 30/24/60
Cela ferait fermer les sessions vieillissant plus de 30 minutes de manière prévisible sans affecter l'application.
La base de données sait-elle que la connexion a été interrompue ou la session est-elle toujours répertoriée dans v $ session? Cela indiquerait, je pense, qu'il est abandonné par le réseau. Savez-vous combien de temps il peut rester inactif avant de rencontrer le problème et si cela ressemble aux valeurs inactives TCP (net.ipv4.tcp_keepalive_time, tcp_keepalive_probes et tcp_keepalive_interval de sysctl si je me souviens bien)? Je ne me souviens pas si les modifications sysctl persistent par défaut, mais cela pourrait être quelque chose qui a été modifié puis réinitialisé par le redémarrage.
En outre, vous pourrez peut-être réinitialiser vos connexions JDBC sans faire rebondir tout le serveur. certainement dans WebLogic, ce qui, à mon avis, ne m'aide pas beaucoup, mais je ne connais pas les équivalents Tomcat.
Vérifiez les paramètres du pool de connexion aux applications plutôt que de modifier les paramètres de délai d'expiration de session sur la base de données Oracle. C'est normal qu'ils passent le temps.
Jetez un coup d’œil ici: http://grails.org/doc/1.0.x/guide/3.%20Configuration.html#3.3%20The%20DataSource
Êtes-vous sûr d'avoir correctement défini le paramètre "pooled"?
Salutations, Lars
MODIFIER:
Votre configuration semble bien au premier regard . Je suis tombé sur ce problème aujourd'hui. Peut-être est-ce lié à votre douleur:
"Boucle infinie d’exceptions si l’application est démarrée alors que la base de données est arrêtée pour maintenance"