Nous avons eu récemment un problème avec la base Oracle utilisée par IBM Tivoli Identity Manager (ITIM pour les intimes). Symptôme : certains traitements restent en "pending" alors qu'ils devraient être terminés, sans message d'erreur.
En regardant dans le fichier trace.log (tivoli/common/CTGIM/logs/trace.log), on trouve des erreurs du type :
[CDATA[java.sql.SQLException: ORA-01591: lock held by in-doubt distributed transaction 5.7.7270
Il s'agit d'une transaction oracle qui reste dans un état indéfini. Les étapes pour débloquer la situation sont les suivantes :
- déterminer le serveur de base de données
- débloquer la transaction dans la base Oracle.
Déterminer le serveur de base de données
Le paramétrage se trouve dans le fichier <ITIM_HOME>/data/enRoleDatabase.properties. Par exemple :
# cd /product/itim/data # more enRoleDatabase.properties ########################################################### # Database information ########################################################### # Database type; The possible values are DB2, ORACLE, MS SQL SERVER database.db.type=ORACLE # ITIM Database owner database.db.owner=enrole # ITIM Database User database.db.user=enrole # ITIM database Password database.db.password=NmNC58X7U9EUuYrLtlhmtQ== ############################################################ # Connection pool ############################################################ # Connection pool properties database.jdbc.connectionPool.initialCapacity=5 database.jdbc.connectionPool.maxCapacity=50 ############################################################ # JDBC driver URL and driver name # ############################################################ # JDBC driver URL database.jdbc.driverUrl=jdbc:oracle:thin:@oraserver01.example.com:1521:ENROLE # JDBC driver name database.jdbc.driver=oracle.jdbc.OracleDriver
Débloquer la transaction Oracle
Il faut se connecter sur le serveur Oracle, et exécuter les commandes suivantes :
sqlplus '/ as sysdba' SQL*Plus: Release 11.2.0.2.0 Production on Tue Jul 3 15:44:33 2012 Copyright (c) 1982, 2010, Oracle. All rights reserved. Connected to: Oracle Database 11g Release 11.2.0.2.0 - 64bit Production SQL> set linesize 132 SQL> col os_user format a15 SQL> select local_tran_id, state, fail_time, force_time, retry_time, os_user from DBA_2PC_PENDING ; LOCAL_TRAN_ID STATE FAIL_TIME FORCE_TIM RETRY_TIM OS_USER ---------------------- ---------------- --------- --------- --------- --------------- 5.7.7270 prepared 27-JUN-12 03-JUL-12 wasadm SQL> rollback force '5.7.7270'; Rollback complete. SQL> execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('5.7.7270'); PL/SQL procedure successfully completed. SQL> select local_tran_id, state, fail_time, force_time, retry_time, os_user from DBA_2PC_PENDING; no rows selected SQL> exit Disconnected from Oracle Database 11g Release 11.2.0.2.0 - 64bit Production
Les deux premières lignes SQL*Plus (set linesize et col os_user format a15) sont uniquement là pour permettre d'avoir le résultat sur une seule ligne.
L'instruction "SELECT xx FROM DBA_2PC_PENDING" permet d'identifier les transactions en attente. On vérifie que le numéro correspond à celui donné dans les logs ITIM.
L'instruction rollback permet d'annuler les transactions en cours, et le PL/SQL purge les transactions perdues.
Par la suite on récupère une base correcte, et les transactions ITIM se terminent correctement.