Comprendre le verrouillage optimiste dans Maximo
Maximo repose sur un mécanisme de verrouillage optimiste (Optimistic Locking) géré via la colonne système ROWSTAMP présente sur chaque table métier. Lorsqu’un utilisateur ou un processus charge un enregistrement, Maximo mémorise son ROWSTAMP. Au moment du SAVE, le framework vérifie que la valeur en base est toujours identique avant d’exécuter l’instruction UPDATE.
Si un autre processus — ou un second pointeur MBO ouvert dans la même transaction — a déjà modifié et validé l’enregistrement entre-temps, Maximo interrompt la sauvegarde pour éviter l’écrasement silencieux des données et affiche :
BMXAA4200E - The record has been modified by another user. Refetch and try again.
L’anti-pattern classique des scripts d’automatisation
Dans 80 % des cas rencontrés en audit technique, l’erreur BMXAA4200E n’est pas due à un second utilisateur humain, mais à l’auto-collision d’un script Jython qui ouvre un MboSet indépendant sur un objet déjà présent dans la transaction courante et appelle explicitement .save().
Schéma 62A — Auto-collision transactionnelle via appel explicite à save()
Comparaison des approches de manipulation MBO
| Approche | Comportement transactionnel | Risque de BMXAA4200E |
MXServer.getMXServer().getMboSet(...) |
Ouvre une transaction isolée hors du contexte parent | Élevé si l’objet est déjà en cours d’édition |
mbo.getMboSet("RELATION") |
Rattache le MboSet enfant à la transaction parente |
Nul (si .save() n’est pas appelé manuellement) |
Appel de set.save() dans un événement SAVE |
Force un commit prématuré et incrémente ROWSTAMP |
Critique (collision garantie) |
Exemple de code Jython : correction d’un script défaillant
Voici comment refactoriser un script qui met à jour un équipement depuis un ordre de travail afin de respecter le cycle transactionnel natif :
# ✅ BONNE PRATIQUE : Utiliser la relation MBO et laisser le framework gérer le commit
from psdi.mbo import MboConstants
assetSet = mbo.getMboSet("ASSET")
if not assetSet.isEmpty():
assetMbo = assetSet.getMbo(0)
# Utilisation des constantes d'accès appropriées sans appel à assetSet.save()
assetMbo.setValue("STATUS", "OPERATING", MboConstants.NOACCESSCHECK)
Si vous devez impérativement exécuter un traitement asynchrone ou isolé (par exemple depuis un bouton d’action personnalisé hors sauvegarde), réinitialisez explicitement l’objet courant après la validation distante via mbo.getThisMboSet().reset().
Diagnostic sur un environnement en erreur
- Activer la journalisation des scripts : passez le logger
maximo.scriptau niveauDEBUGdans l’application Logging. - Rechercher les appels
.save(): interrogez la tableAUTOSCRIPTen lecture seule pour lister tous les scripts contenant l’instruction.save(.
-- Détecter les scripts d'automatisation appelant explicitement .save()
SELECT autoscript, description, status, scriptlanguage
FROM autoscript
WHERE UPPER(source) LIKE '%.SAVE(%'
AND status = 'ACTIVE';
- Vérifier les points de lancement : croisez les résultats avec
SCRIPTLAUNCHPOINTpour identifier ceux déclenchés surOBJECT(événementsADD,UPDATE,DELETE) ouATTRIBUTE(VALIDATE,ACTION).
Schéma 62B — Règle d’or de validation dans le cycle MBO
Limites et cas particuliers
Dans le cadre d’un Cron Task ou d’une intégration entrante MIF traitant des lots volumineux, le commit transactionnel doit être maîtrisé par paquets (batch). Si un même enregistrement est modifié deux fois au sein d’un même lot XML, activez le paramètre mxe.int.enableoptimisticlock ou triez les messages entrants par clé métier afin d’éviter les accès concurrents entre fils d’exécution (JMS Consumers).
Checklist de revue de code Jython
- Tous les
MboSetliés à l’enregistrement courant sont-ils récupérés viambo.getMboSet("RELATION")? - Les appels à
.save()sont-ils strictement absents des scripts liés aux événements de sauvegarde ? - Tout
MboSetouvert manuellement viaMXServerdans un script autonome est-il fermé dans un bloctry...finally? - Le flag
MboConstants.NOACCESSCHECKest-il utilisé à bon escient sans contourner les règles métier critiques ?
À retenir : dans Maximo, un script rattaché au cycle de vie d’un objet ne doit jamais décider lui-même du moment du commit ; il prépare les données et laisse le framework MBO valider l’ensemble atomiquement.
Références
- IBM Docs : Automation Script Best Practices and Transaction Management.
- IBM Support : Understanding BMXAA4200E Optimistic Locking in Maximo Framework.
Commentaires
Une question ou un retour d’expérience sur cette procédure ? Partagez-le ici.
Connectez-vous pour participer à la discussion.
Se connecter