La fonction journal permet de gérer des cycles de validation dans vos programmes Il s'agit d'atomiser un groupe d'actions sur la base de données C'est à dire de faire en sorte que ce groupe d'actions soit réalisé EN TOTALITE ou pas du tout. Les fichiers concernés doivent être journalisés(et tous par le même journal) Vous allez démarrer le contrôle de validation par la commande CL STRCMTCTL puis appeler le pgm RPG ou COBOL celui-ci doit déclarer la liste des fichiers qui sont sous contrôle de validation (syntaxe dépendante du langage) vous terminez par ENDCMTCTL |
En RPG3 , une specif F de continuation par fichier FPRODUIT UF E K DISK F KCOMIT En RPG4 , une specif F avec le mot-clé COMMIT FPRODUIT UF E K DISK COMMIT le mot-clé COMMIT du RPG4 admet en argument une variable de type indicateur (N) qui rend le travail sous commitment control dépendant du fait que cet indicateur soit vrai (*ON ou '1') en COBOL FILE-CONTROL. SELECT PRODUIT ASSIGN TO ... I-O-CONTROL. COMMITMENT CONTROL FOR PRODUIT. (liste de fichiers possible) |
Puis votre programme va réaliser un certain nombre d'actions sur la base de données (ajout, mises à jour, etc ...) Ces actions SONT répercutées dans les fichiers , MAIS : TOUS les enregistrements manipulés restent verrouillés Ces modifications sont en instance (non définitives) Elles peuvent être validées en fin de transaction C'est vous qui déterminez ce qu'est une transaction, suivant l'endroit où vous placez l'ordre de validation, la fréquence. COMIT en RPG, COMMIT en RPG4 et COBOL Le système admet 500.000.000 lignes à l'intérieur d'UNE transaction, mais toute transaction dépassant 2000 lignes va probablement avoir un impact assez lourd sur les performances. |
Elles peuvent être invalidées (idem recouvrement arrière [RMVJRNCHG], mais uniquement sur les actions réalisées par votre programme) MISE à jour défaites, ajouts retirés, enregistrements supprimés ré-écrits,. ROLBK en RPG (3 ET 4) , ROLLBACK en COBOL. Les mêmes ordres peuvent être demandés en CL Cdes COMMIT et ROLLBACK (en cas de plantage du pgm RPG, par ex) LE SYSTEME ASSURE QU'EN CAS DE FIN ANORMALE (du job, du système, ...) IL EXECUTERA UN ROLLBACK IMPLICITE A l'IPL suivant s'il le faut. |
Options du STRCMTCTL LCKLVL : *CHG tous les enregistrements modifiés,ajoutés sont verrouillés (pas les enregistrements lus) *CS = idem *CHG plus verrouillage des enregistrements lus (un au maxi = une lecture déverrouille le précédent) *ALL = idem *CHG plus verrouillage de TOUS les enregistrements lus jusqu'à COMMIT/ROLLBACK. NFYOBJ *NONE ou un nom en RPG vous pouvez lors d'un COMMIT demander au système de mémoriser des informations (Facteur 1 du COMMIT) en cas de fin anormale, ces informations seront écrites dans l'objet de notification afin que votre programme puisse proposer une reprise. |
Vous devez alors indiquer - un nom d'objet - un type (*MSGQ, *DTAARA, *FILE) - ainsi qu'un nom de membre si *FILE Le plus simple est probablement la notion de fichier qui sera lu en entrée par le pgm, s'il contient des informations, c'est que la dernière transaction ne s'est pas terminée normalement. Il faut probablement mémoriser dans le fichier l'utilisateur (voire le terminal) et lire le fichier par clé en début de programme. Vous pouvez alors tenter de proposer une reprise avec les données utiles stockées dans le fichier. la suppression de l'enregistrement dans le fichier de notification est à votre charge ==> pensez-y ! |
Contrôle de validation et intégrité référentielle Dans la cadre d'une intégrité référentielle, si l'une de deux règles en cas de mise à jour ou de suppression n'est pas à *RESTRICT (vérification avant de faire), le contrôle de validation doit être actif. s'il ne l'est pas, le système démarre un contrôle de validation nommé "QDBCMTDFN" (passez WRKCMTDFN pour le voir) Contrôle de validation et groupes d'activation Un certain nombre de paramètres systèmes concernant la gestion de fichier peuvent maintenant être liés à la notion de groupe d'activation. On parle de champ d'application ou de portée, pour indiquer si un paramètre est valide pour l'ensemble du job ou uniquement pour les pgms d'un groupe d'activation (celui dans lequel se trouve le pgm ayant passé la commande) |
A/ la portée d'une substitution avec OVRDBF OVRSCOPE( ) B/ la portée d'une ouverture avec OPNSCOPE( ) [cdes OVRDBF,OPNDBF,OPNQRYF] C/ et enfin, le contrôle de validation est lancé pour le groupe d'activation en cours, ou bien pour l'ensemble du job. STRCMTCTL CMTSCOPE *ACTGRP : lancé pour le groupe d'activation *JOB : lancé pour le job. la valeur par défaut (*ACTGRP) permet d'avoir plusieurs transactions en cours, en même temps, portant sur des fichiers différents. Donc, de valider au sein d'une application, une transaction en cours (COMMIT), ou bien de l'invalider, sans que cela n'ait de répercussion sur les autres applications (autres groupes d'activation). Pour gérer tous les contrôles de validation actifs, la nouvelle commande : WRKCMTDFN est utile. |
Gestion des définitions de validation Système: AS400 Indiquez vos options, puis appuyez sur ENTREE. 5=Afficher état 12=Gérer travail 14=Validation forcée 16=Invalidation forcée ... Définition Unité Resync en Opt validation Travail Util Numéro exécut cours *DFTACTGRP DSPO4 QPGMR 091010 *NONE NON QDBCMTDFN DSP04 QPGMR 091010 *NONE NON La colonne Définition de validation peut afficher les valeurs suivantes : *DFTACTGRP ou un nom de groupe d'activation (DSPJOB / opt 18 pour le voir) *JOB s'il s'agit un contrôle de validation lancé au niveau JOB un nom commencant par Q pour un contrôle de validation lancé par le système *TNSOBJ pour un contrôle de validation lié à une transaction (Api XA/Xopen) nb : vous pouvez aussi utiliser Iseries Navigator pour voir tout cela. |
Ajouter une ressource par API Il faut définir une ressource sous contrôle de validation en lui associant un paramètre de 80 c. et un pgm d'exit. A chaque action du control de validation (commit ou rollback) le pgm d'exit sera appellé et recevra les 80 c. (entre autre) Ajouter une ressource : QTNADDCR - BIN(4,0) zone de retour (à utiliser en fin avec QNTRMVCR) - CHAR(10) nom de la ressource - CHAR(20) nom qualifé du pgm d'exit - CHAR(80) informations à envoyer au pgm d'exit - CHAR(1) appel du pgm à l'IPL (O ou N) - CHAR(??) code erreur |
Le pgm d'exit reçoit deux paramètres 1/ les informations liées à la ressource (80 c.) 2/ une structure composée comme suit: 1 à 4 BIN(4) lg des infos (toujours 32) 5 à 5 CHAR(1) commit (C) ou rollback (R) 6 à 6 CHAR(1) Appel lors de l'IPL (O ou N) 7 à 10 CHAR(4) réservé 11 à 11 CHAR(1) état du processus (job) lors de l'appel '0' processus n'est PAS en phase de fin '1' processus en phase de fin NORMALE '2' processus en phase de fin ANORMALE 12 à 31 CHAR(20) réservé |
Enlever une ressource : QTNRMVCR - BIN(4,0) zone de retour reçue de QTNADDCR - CHAR(??) code erreur Modifier options du contrôle de validation QTNCHGCO - CHAR(??) infos à modifier BIN(4) lg des infos à modifier infos à modifier sous forme de flags CHAR(1) principalement liées au "two phases commit" - CHAR(??) code erreur |
Informations sur le contrôle de validation QTNRCMTI - CHAR(??) variable en retour (format CMTI0100) 1 à 4 BIN(4,0) octets renvoyés 5 à 8 BIN(4,0) octets valides 9 à 9 CHAR(1) status I=inactif,L=actif(local) R=actif(remote), A=actif sans ressources 10 19 CHAR(10) verrouillage 20 20 portée du contrôle de validation A = groupe d'activation J = JOB > plus les options modifiables par QTNCHGCO - BIN(4,0) lg de la variable en retour - CHAR(8) format = CMTI0100 - CHAR(??) code erreur |
Programme trigger et contrôle de validation : FONCTIONNEMENT HORS CONTROLE DE VALIDATION Si le programme applicatif et le programme trigger ne s'exécutent pas sous contrôle de validation, toute erreur du programme trigger laissera les fichiers dans l'état au moment de l'erreur. FONCTIONNEMENT SOUS CONTROLE DE VALIDATION Si le programme applicatif seul s'exécute sous contrôle de validation, l'opération COMMIT du programme applicatif s'applique uniquement à ses propres modifications. Si le programme trigger seul s'exécute sous contrôle de validation, les modifications effectuées par le programme trigger sont validées quand : - le groupe d'activation se termine (COMMIT implicite) - une opération de COMMIT est demandée par le programme |
Si le programme applicatif et le programme trigger s'exécutent sous le même contrôle de validation, un arrêt anormal du programme trigger entraînera le Rollback de toutes les opérations qui lui sont associées. Un Rollback est également effectué sur l'opération de modification d'origine. Ceci nécessite que le programme trigger envoie un message d'exception quand l'erreur est détectée. Les deux programmes sont alors fortement couplés , c'est la solution pour un trigger chargé de détecter des erreurs pouvant annuler l'action B de D. Si le programme applicatif et le programme trigger s'exécutent sous des contrôles de validation différents, l'opération COMMIT du programme applicatif n'agit que sur son propre contrôle de validation. La validation des modifications du programme trigger doit être effectuée de façon distincte. les deux programmes sont faiblement couplés, c'est la solution pour un trigger chargé de répercuté des actions (dans un autre fichier) |
SQL et COMMIT/ROLLBACK si vous réalisez vos Entrées/Sorties par SQL : 1/ vous ne passez plus la commande STRCMTCTL, mais renseignez le paramètre COMMIT : > sur la commande STRSQL ou par F13 ensuite. > lors de la compilation (CRTSQLRPGI, par exemple) > dans le paramétrage du driver ODBC/JDBC. > dans la clause WITH sur l'ordre SQL lui-même *NONE ou *NC : Vous travailler HORS contrôle de validation *CHG ou *UR : les objets manipulés par les ordres SQL suivants : ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON RENAME, REVOKE ainsi que les lignes ajoutées (Insert) détruites (DELETE) et modifiées (UPDATE) sont verouillées jusqu'à la fin de transaction Les modifications non validées des autres travaux sont visibles , car pas de verrou en lecture. |
*CS : idem *CHG, PLUS une ligne par table en lecture. Pour un Select simple, la ligne est verrouillée PUIS libérée (il ne s'agit que de tester sa disponibilité) Pour un curseur chaque ligne lue est verrouillée par FETCH jusqu'à la lecture de la ligne suivante. sauf à préciser : KEEP LOCKS la ligne est alors verrouilée jusqu'à la fin de la transaction ou fermeture du curseur Les modifications non validées des autres travaux ne sont donc pas visibles , la ligne n'étant pas accessible ! |
la version 7 vient compléter ce choix en placant en fin d'ordre une phrase précisant la concurrence d'accès: .......................................................................... : - WAIT FOR OUTCOME : : Attendre que les lignes verrouillées soient libérées (CS ou RS) : : - SKIP LOCKED DATA : : les lignes verrouillées sont ignorées (NC, UR, CS, ou RS) : : - USE CURRENTLY COMMITTED : : Utiliser les (anciennes) valeurs déjà validées (SELECT sous CS) : :........................................................................: *ALL ou *RS : idem *CS, sauf verrouillage de TOUTES les lignes lues pour un curseur Pour un Select simple, la ligne est verrouillée PUIS libérée, sauf à préciser USE AND KEEP EXCLUSIVE LOCKS auquel cas elle est verrouillée jusqu'au COMMIT. des lignes peuvent être inserées dans le fichier pendant la transaction par d'autres JOB. |
*RR : idem *ALL, sauf que les tables manipulées par INSERT, UPDATE, DELETE et SELECT sont verrouillées en usage Exclusif , empéchant l'insertion de lignes. On ne voit pas les transactions en cours et la même requête passée dans la même transaction produit le même résultat (Repeatable Read !) récapitulatif ! NC ! UR ! CS ! RS ! RR ! !----!----!----!----!----! Accès aux lignes en cours de modfication ? ! O ! O ! N ! N ! N ! ------------------------------------------------------------------------- Mise à jour des lignes en cours de transaction?! N ! N ! N ! N ! N ! ------------------------------------------------------------------------- Le même ordre produit même résultat ? ! N ! N ! N ! N ! O ! ------------------------------------------------------------------------- une ligne mise à jour est modifiable ailleurs? ! O ! 1 ! 1 ! 1 ! 1 ! ------------------------------------------------------------------------- une ligne lue est modifiable ailleurs ? ! 2 ! 2 ! 2 ! N ! N ! ------------------------------------------------------------------------- 1 : Non la ligne est verrouillé jusqu'au COMMIT, après Oui bien sûr. 2 : si le curseur est FOR UPDATE Non, sinon Oui. |
2/ vous validez avec l'ordre SQL COMMIT (vous invalidez par ROLLBACK) ATTENTION, l'ordre SQL COMMIT possède un paramètre important HOLD : - Les ressources sont suspendues. Les curseurs actifs ne sont pas désactivés , les instructions SQL préparées sont conservées et toutes les ressources acquises pendant la transaction sont suspendues. (sans) - Les ressources ne seront pas suspendues. Les curseurs actifs sont désactivés, les instructions SQL préparées sont supprimées et les ressurces suspendues libérées. Un curseur peut etre déclaré WITH HOLD ou WITHOUT HOLD s'il est déclaré WITH HOLD, il ne sera pas désactivé, meme en cas de COMMIT simple. |
Cas particulier du langage SQL/PSM (procédures cataloguées) les instructions d'une procédure cataloguées peuvent être regroupées comme un tout (on parle d'instruction complexe, "compound statement") corps général d'une procédure cataloguée écrite en SQL/PSM CREATE PROCEDURE bibliotheque/procédure ( parametres ) language SQL BEGIN ATOMIC | NOT ATOMIC DECLARE (partie déclaration) .../... (instructions) ; END les blocs d'instructions (BEGIN / END) peuvent être imbriqués |
PSM est en fait un L4G qui génére un source C dans QTEMP et créé un pgm. ce pgm est compilé dans le groupe d'activation *CALLER (toujours) si vous indiquer NOT ATOMIC ou si vous n'indiquez rien, vous travaillez hors transaction, sauf transaction en cours, démarrée par STRSQL, par ex Exemple : --- --- test d'une procédure simple --- elle prend le niveau de commit de la session SQL --- le DELETE du fichier client est impossible car certains fichiers --- enfants (livraisons et factures) ne sont pas journalisés. --- le DELETE du fichier facture n'est possible qu'avec COMMIT(*NONE) --- le pgm ne se plante alors qu'à la deuxième instruction. create procedure af4test/prc1 () language SQL begin delete from af4test/factures; delete from af4test/clients where nocli = 4; end |
--- --- test d'une autre procédure simple --- ici, les deux fichiers sont journalisés --- le DELETE du fichier ma_cave est toujours possible --- le DELETE du fichier pays est impossible, il y a des producteurs --- --- sans ATOMIC, le fichier cave est vide, même en cas de prb create procedure af4test/prc2 () language SQL begin delete from bdvin9/ma_cave; delete from bdvin9/pays where pays_code=11; end ........................................................................... : > call af4TEST/prc2 : : Suppression impossible à cause de la contrainte référentielle Q_BDVIN : : > select * from bdvin9/ma_cave ==> fichier vide : :.........................................................................: --- --- avec ATOMIC, le fichier cave est plein suite à cette manipulation --- ==> SQL a fait un ROLLBACK, d'ailleur le pgm est compilé COMMIT(*CHG) |
vous pouvez dans la partie déclaration, déclarer des HANDLER on déclare 1/ l'erreur (code ou nom-condition déclaré lui aussi) 2/ le traitement 3/ la reprise après traitement. (1) DECLARE ------------------------ HANDLER FOR code-erreur---------> ! ! (3)!--CONTINUE----! ! ! !--EXIT--------! ! ! !--UNDO--------! >-------instruction SQL ; (2) dans tous les cas on exécute le traitement (2) avant de gérer la reprise (3) |
la reprise : CONTINUE = on continue le code en séquence. (si l'erreur a lieu dans un IF, CASE, WHILE, on sort et on se débranche à l'instruction qui suit le IF ...) EXIT = on va au END UNDO = on annule tous les changements (ROLLBACK) puis EXIT, ce qui implique BEGIN ATOMIC ! et enfin, la V5R20 apporte un nouveau niveau de granularité - SAVEPOINT Cette notion permet de matérialiser des étapes dans une transaction offrant la possibilité de revenir à une étape précise et non au début de la transaction en cas de ROLLBACK. |
un point de reprise est posé par l'instruction SAVEPOINT UPDATE client ... ; SAVEPOINT MAJ ON ROLLBACK RETAIN CURSORS ; DELETE FROM CLIENTS ... ; DELETE FROM COMMANDES ; SAVEPOINT DLT ON ROLLBACK RETAIN CURSORS ; INSERT INTO ... ; IF xxx ROLLBACK TO SAVEPOINT MAJ ELSE RELEASE SAVEPOINT ; ON ROLLBACK RETAIN CURSORS, permet de garder le(les) curseur(s) ouverts ON ROLLBACK RETAIN LOCKS , permet de garder les verrouillages/ligne RELEASE SAVEPOINT, libère (détruit) le point de reprise |
Exemple (en RPG4) : Dligne E DS extname(fichier) /free nom = 'test1' ; exsr ecriture ; nom = 'test2' ; exsr ecriture ; // point de sauvegarde exsr savepointS1; nom = 'test3' ; exsr ecriture ; // annulation de CETTE écriture par ROLLBACK TO SAVEPOINT exsr rollbackS1 ; nom = 'test4' ; exsr ecriture ; // validation, je dois avoir les lignes 1,2 ET 4 (exact). exsr commit ; *inlr = *on ; /end-free |
C ecriture begsr C/EXEC SQL C+ INSERT INTO FICHIER VALUES(default, :nom) C/END-EXEC c endsr C savepointS1 begsr C/EXEC SQL C+ SAVEPOINT s1 C/END-EXEC c endsr C rollbackS1 begsr C/EXEC SQL C+ ROLLBACK to SAVEPOINT s1 C/END-EXEC c endsr C commit begsr C/EXEC SQL C+ COMMIT C/END-EXEC c endsr |
+------------------------------------------------------------------------+ | Principaux codes journaux liés au COMMIT | +------------------------------------------------------------------------+ | | | | C BC | démarrage du contrôle de validation | +----------+-------------------------------------------------------------+ | | | | C SC | démarrage d'un cycle | +----------+-------------------------------------------------------------+ | | | | C CM | Commit | +----------+-------------------------------------------------------------+ | | | | C RB | Rollback | +----------+-------------------------------------------------------------+ | | | | C LW | Fin de transaction, écrit uniquement avec OMTJRNE(*NONE) | +----------+-------------------------------------------------------------+ | | | | C EC | arrêt du contrôle de validation | +----------+-------------------------------------------------------------+ |
+------------------------------------------------------------------------+ | | | | C SB | Début d'un transaction imbriquée ou SAVEPOINT | +----------+-------------------------------------------------------------+ | | | | C SQ | libération d'un SAVEPOINT ou commit d'une transaction | | | imbriquée (Procédures cataloguées) | +----------+-------------------------------------------------------------+ | | | | C SU | Rollback d'un SAVEPOINT ou d'une transaction imbriquée | +----------+-------------------------------------------------------------+ Ces trois dernières entrées ne sont écrite que de manière optionnelle. pour les écrire pour un journal donné (MONJOURNAL dans MABIB) pour ce JOB : ADDENVVAR ENVVAR(QTN_JRNSAVPT_MABIB_MONJOURNAL) VALUE(*YES) pour les écrire pour TOUS les journaux, TOUS les JOBS : ADDENVVAR ENVVAR(QTN_JRNSAVPT_*ALL_*ALL) VALUE(*YES) LEVEL(*SYS) |