La nuova gestione delle lock prevede l’utilizzo di un nuovo file che andrà a sostituire il vecchio DC§FOL/LX_FOL.
Il nuovo file si chiama EDGSLK.
Questo nuovo file è compatibile con i programmi che gestivano le “vecchie lock” ma sono stati aggiunti i dati relativi all’id sessione, al framework e al BO che sono indispensabili per la gestione delle lock su applicativo Web.
E’ stata creata un RP che gestisce la lock; la reusable part restituisce un valore per indicare se la lock è andata a buon fine. In caso il record fosse già bloccato restituisce due messaggi
£p_message - L'informazione richiesta è in uso dall'utente XXXXXXXX dalle ore XX:XX:XX
£p_info - Nome framework/File/RRN
Nel caso si facciano le lock da una Wam, questa RP è stata inglobata in DMWAMHND.
I metodi che devono essere usati sono
- Blocco - um_Lock
- Blocco con Lock Free - um_LockFree
- Sblocco - um_UnLock
- Pulisco le lock - um_ClearLock
Se si deve fare una lock su una funzione Full-RMDLX si potrà usare la RP EDLOCK (non ancora implementato - al momento utilizzare EDSYS17)
Nel caso di funzioni non full-RDMLX si può continuare ad usare EDSYS17 (che gestirà la nuova lock al momento in cui viene impostato il flag locktype=2).
Le lock vanno implementate su TUTTE le wam in cui si fanno delle operazioni sui dati.
Si deve fare la distinzione tra :
- Command a livello di Instance List con Lock – Per bloccare si devono richiamare i metodi um_Lock (o um_LockFree) per il file o i file interessati.
Nel caso in cui è possibile sbloccare al momento del tasto Salva si deve sbloccare il record con il metodo um_unLock e disabilitare il tasto Salva.
Lock con RRN
E' la classica Lock fatta con l'rrn del file che si vuole bloccare
Si utilizza il metodo um_Lock.
I parametri da passare da una wam sono:
- Nome File
- RRN
- Business Object
Si può scegliere opzionalmente se gestire le lock multiple.
Lock Free
Si utilizza il metodo um_LockFree.
I parametri da passare sono:
- Nome File
- LockFree (esempio n.ordine/n.riga su PRVARG)
- Business Object
Si può scegliere opzionalmente se gestire le lock multiple.
UnLock
Si utilizza per sbloccare il record.
I parametri da passare sono:
- Business Object
- File (opzionale)
- RRN (opzionale)
- LockFree (opzionale)
- Command a livello di Instance List senza Lock – si deve inserire la clear Lock (solo se per l’instance a cui fa riferiemento c’è almeno un command con lock)
ClearLock
Pulisce tutte le lock per Framework- Sessione- Utente.
Se chiamato da una wam (tramite DMWAMHND) non deve ricevere nessun parametro.
- Command a livello di Business Object con Lock – attualmente non gestite in quanto tutte le operazioni "interattive" che modificano un singolo oggetto devono essere inserite a livello di Instance List.
Come implementare la gestione delle lock sulle wam
- Nelle wam già esistenti
1 - Modificare i filtri per aggiungere la Clear Lock quando viene caricata l'instance list.
********** ===================================================================================
********** METHOD ROUTINE: CERCA
********** ===================================================================================
--MTHROUTINE NAME(um_WAMCerca)
| **********
| £R_TOTERR := *ZERO
| **********
| --BEGINCHECK KEEP_COUNT(£R_TOTERR)
| |
| | ...
| | ...
| |
| --ENDCHECK IF_ERROR(*NEXT)
| **********
| --IF (£R_TOTERR > 0)
| | **********
| | £ThisFilter.avShowMessages := TRUE
| | **********
| | RETURN
| --ENDIF
|
|
| ********** pulisco le lock del framework
| £DMWAMHND.um_ClearLock
|
|
| £avListManager.Beginlistupdate
|
| £avListManager.Clearlist
|
| ....
| ....
| ....
|
|
|
--ENDROUTINE
2 - Modificare i command con lock
********** ====================================================================
********** LEGGO IL RECORD DI MODA00F
********** ====================================================================
CHANGE FIELD(£LOCKRIS) TO(*NULL)
--BEGIN_LOOP
| **********
| FETCH FIELDS(*all) FROM_FILE(MODA00F) WITH_KEY(£MONROR) RETURN_RRN(£LOCKRRN)
| **********
V--LEAVE IF('(£lockris *ne *blank) *or (£io$sts *ne ''OK'') ')
|
| ********** Se non sono abilitato alla scrittura non effettuo la lock
V--LEAVE IF(*Not (£DMWAMHND.up_canwritebo))
|
| **********
| ********** Richiamo LOCK_OBJECT per MODA00F
| **********
|
| £DMWAMHND.Um_lock P_FILE(MODA00F) P_RRN(£LOCKRRN) P_BUSINESSOBJ(£THISHANDLER.AVOBJECTTYPE) P_RESULT(£LOCKRIS) P_MESSAGE(£LOCKMSG) P_INFO(£R_DE100)
|
| **********
| ********** Nel caso non si riuscisse a bloccare il record emetto il messaggio
| **********
|
| | --IF COND(£LOCKRIS *EQ 'ER')
| | **********
| | ********** Disabilito il tasto SALVA ed altri bottoni
| | **********
| | £DMWAMHND.up_ButtonHandler.um_STDButtonEnabled PITEMBOTTONE(1) PENABLED(false)
| | £DMWAMHND.up_ButtonHandler.um_STDButtonEnabled PITEMBOTTONE(11) PENABLED(FALSE)
| | £DMWAMHND.up_ButtonHandler.um_FUNButton PITEMBOTTONE(1) PGESTITO(FALSE) PCAPTION(*MTXTAGMN108)
| |
| | MESSAGE MSGTXT(£LOCKMSG)
| | MESSAGE MSGTXT(£R_DE100)
| |
| | £ThisHandler.avShowMessages := TRUE
V----LEAVE
| --ENDIF
--END_LOOP
3 - Modificare i command senza lock se riferiti ad una instance list che ha anche command con lock
**********
--EVTROUTINE HANDLING(£avFrameworkManager.uExecute) OPTIONS(*NOCLEARMESSAGES *NOCLEARERRORS)
| **********
| £DMWAMHND.um_ExecuteWAM FRAMEWORKMANAGER(£avFrameWorkManager) TIPO(COMMAND) LISTMANAGER(£avListManager) HANDLERMANAGER(£ThisHandler) FASTPARTMANAGER(£FastPart)
|
|
| ********** pulisco le lock del framework
| £DMWAMHND.um_ClearLock
|
|
| ********** ====================================================================
| ********** LEGGO ISTANCE LIST
| ********** ====================================================================
| £avListManager.GetCurrentInstance NKEY1(£CPYORD) FOUND(£FLTROVATO)
|
|
| ********** ====================================================================
| ********** LEGGO MODA00F
| ********** ====================================================================
| FETCH FIELDS(£MOKSG) FROM_FILE(MODA00F) WITH_KEY(£CPYORD)
|
| ....
| ....
|
--ENDROUTINE
- Nelle nuove wam
1 - Filtro - la clear lock viene già inserita dalla template di creazione del filtro
- in caso di gestione della paginazione della Instance List richiamare la ClearLock nella routine di paginazione
(prima di BeginListUpdate)
2 - Command con Lock - utilizzare la template LOCKFETCHW
3 - Command con Lockfree - utilizzare la template LOCKFREE
4 - Command senza Lock - la clear lock viene già inserita dalla template di creazione del Command
Se le lock avvengono da un terminalino, andrà specificato nel Buisness Object
es:
£DMWAMHND.um_lock P_FILE(PWIPAR) P_RRN(£rrncart) P_BUSINESSOBJ('TERMINALINO_PRODUZIONE') P_LOCKMULTIPLE(TRUE) P_INFO(£LOCKMSG) P_MESSAGE(£LOCKMSG) P_RESULT(£LOCKRIS)
Gestione lock multiple
Nel caso in cui devo fare una medesima operazione su + record dello stesso file (esempio tutte le righe di un ordine), a differenza di ciò
che avveniva nella vecchia gestione dove bloccavo un record alla volta e aggiornavo, possiamo gestire la lock multipla.
Questa implementazione è stata necessaria in quanto nel web non possiamo avere tempi di attesa "lunghi" (es. attesa che si sblocchi un record)
in quanto l'operatore potrebbe chiudere la finestra e interrompere l'elaborazione con le relative conseguenze.
Vecchia gestione
1 --SELECT FIELDS(£RGKFA) FROM_FILE(RIGO00F) WHERE(£RGPASZ *EQ *ZERO) WITH_KEY(£MONROR) RETURN_RRN(£LOCKRRN)
2 |
3 | ********** =======================================================
4 | ********** RICHIAMO LOCK_OBJECT PER RIGO00F
5 | ********** =======================================================
6 | --BEGIN_LOOP
7 | | CHANGE FIELD(£LOCKPF) TO(RIGO00F)
8 | | CHANGE FIELD(£LOCKFREE £LOCKF12) TO(*NULL)
9 | | EXCHANGE FIELDS(£LOCKPF £LOCKRRN £LOCKFREE £LOCKF12 £R_ALF120 £R_ALF240)
10 | | CALL PROCESS(*DIRECT) FUNCTION(EDSYS17) EXIT_USED(*NEXT) MENU_USED(*NEXT)
11 | V--LEAVE IF('(£lockris *eq ''OK'') or (£lockris *eq ''IG'') or (£lockkey *eq ''MENU'')')
12 | --END_LOOP
13 |
14 | CHANGE FIELD(£LOCKDEL) TO(*NULL)
15 | EXECUTE SUBROUTINE(LEGGIRIGO)
16 |<-CONTINUE IF('£lockdel *eq ''Y''')
17 |
18 | £RGKFA := £MOKFA
19 | UPDATE FIELDS(£RGKFA) IN_FILE(RIGO00F) WITH_RRN(£LOCKRRN)
20 |
21 | ********** =======================================================
22 | ********** Richiamo UNLOCK_OBJECT per RIGO00F
23 | ********** =======================================================
24 | CHANGE FIELD(£LOCKPF) TO(RIGO00F)
25 | CHANGE FIELD(£LOCKRRN) TO(*NULL)
26 | EXCHANGE FIELDS(£LOCKPF £LOCKRRN £R_ALF120 £R_ALF240)
27 | CALL PROCESS(*DIRECT) FUNCTION(EDSYS17) EXIT_USED(*NEXT) MENU_USED(*NEXT)
28 |
29 --ENDSELECT
Nuova gestione
33 CHANGE FIELD(£LOCKRIS) TO(*NULL)
34 ********** Blocco tutti i record che dovrò aggiornare
35 --SELECT FIELDS(£RGKFA) FROM_FILE(RIGO00F) WHERE(£RGPASZ *EQ *ZERO) WITH_KEY(£MONROR) RETURN_RRN(£LOCKRRN)
36 |
37 | ********** Richiamo LOCK_OBJECT per RIGO00F
38 |
39 | £DMWAMHND.UM_LOCK P_BUSINESSOBJ(£THISHANDLER.AVOBJECTTYPE) P_FILE(RIGO00F) P_LOCKMULTIPLE(TRUE) P_RRN(£LOCKRRN) P_RESULT(£LOCKRIS) P_MESSAGE(£LOCKMSG) | P_INFO(£R_DE100)
40 |
41 | ********** Se non riesco a bloccarlo emetto un messaggio ed esco
42 | --IF COND(£LOCKRIS *EQ 'ER')
43 | | £DMWAMHND.up_ButtonHandler.um_STDButtonEnabled PITEMBOTTONE(1) PENABLED(false)
44 | |
45 | | MESSAGE MSGTXT(£LOCKMSG)
46 | | MESSAGE MSGTXT(£R_DE100)
47 | |
48 | | £ThisHandler.avShowMessages := TRUE
49 V----LEAVE
50 | --ENDIF
51 |
52 --ENDSELECT
53
54 ********** Nel caso in cui il bloccaggio di tutti i record sia andato a buon fine
55 --IF COND(£LOCKRIS *NE 'ER')
56 |
57 | ********** aggiorno i record
58 | --SELECT FIELDS(£RGKFA) FROM_FILE(RIGO00F) WHERE(£RGPASZ *EQ *ZERO) WITH_KEY(£MONROR)
59 | |
60 | | £RGKFA := £MOKFA
61 | | UPDATE FIELDS(£RGKFA) IN_FILE(RIGO00F)
62 | |
63 | --ENDSELECT
64 |
65 | ********** sblocco tutti i record
66 | £DMWAMHND.um_unlock P_BUSINESSOBJ(£THISHANDLER.AVOBJECTTYPE) P_FILE(RIGO00F)
67 |
68 --ENDIF
SwitchLock
Nei casi in cui devo fare una lock su una WAM e poi il batch richiede di utilizzare la stessa lock per tener bloccato il record è necessario utilizzare la SwitchLock.
Nella Wam andrà utilizzata prima della SUBMIT la template LOCKSWWAM
* in caso di lock singola
477 | | £LOCKPF := BUOP00F
478 | | £EDWAMHND.um_SwitchLock P_BUSINESSOBJ(£thishandler.AVOBJECTTYPE) P_FILE(£LOCKPF) P_RRN(£LOCKRRN)
* in caso di lock Multipla
479 | |
480 | | --SELECTLIST NAMED(£RRN_CART)
481 | | | £LOCKPF := CART00F
482 | | | £EDWAMHND.um_SwitchLock P_BUSINESSOBJ(£thishandler.AVOBJECTTYPE) P_FILE(£LOCKPF) P_RRN(£CARTRRN)
483 | | --ENDSELECT
484 | | --SELECTLIST NAMED(£RRN_RIGO)
485 | | | £LOCKPF := RIGO00F
486 | | | £EDWAMHND.um_SwitchLock P_BUSINESSOBJ(£thishandler.AVOBJECTTYPE) P_FILE(£LOCKPF) P_RRN(£RIGORRN)
487 | | --ENDSELECT
Alla SUBMIT deve essere passato come parametro il campo £LOCKNBR che dovrà avere il job number dell'esecuzione della Wam nel momento in cui effettua la lock. (£LOCKNBR := *JOBNBR)
Ad esempio se la lock viene effettuata nell'execute, l'assegnazione deve avvenire in quel momento e deve essere messo il campo in WEB_MAP.
Nella funzione Batch lanciata in SUBMIT deve essere utilizzata ad inizio funzione la template LOCKSWBATC
214 FUNCTION OPTIONS(*NOMESSAGES *DEFERWRITE *MLOPTIMISE *DIRECT)
215
216 ********** se viene passato £locknbr vuol dire che ho una switch lock
217 ********** Usare anche la template lockswwam
218 --IF COND(£LOCKNBR *NE *BLANK)
219 | EXCHANGE FIELDS(£LOCKNBR)
220 | CALL PROCESS(*DIRECT) FUNCTION(EDLKNBR) EXIT_USED(*NEXT) MENU_USED(*NEXT)
221 --ENDIF
Questo permetterà poi al batch quando andrà a effettuare nuovamente la lock di riconoscere che è se stesso e proseguire nell'elaborazione senza che nessun altro processo possa tenerlo in attesa della lock.
UnlockBatch
Per i programmi RDMLX che utilizzano EDLOCK è stato creato un nuovo metodo chiamato um_UnlockBatch.
Questo metodo va utilizzato SOLO nei programmi che vengono chiamati in Batch.
Ricordiamo che nei programmi batch i campi Framework, BO, IDSessione devono essere vuoti per differenziarle da quelle WEB.
Se si vuole utilizzare EDLOCK per creare le lock nei programmi Batch RDMLX i campi Framework, BO, IDSessione dovranno essere vuoti.
Il metodo rimane valido anche per le lock Multiple e per le lock che hanno subito lo SwitchLock da WEB a Batch.
Esempio.
33 | --SELECT FIELDS(£BUKBO) FROM_FILE(BUOC01L) WITH_KEY(£PGKBUO)
34 | | £CANROR £CANRRG £LOCKRIS := *NULL
35 | | --BEGIN_LOOP
36 | | | FETCH FIELDS(£CANROR £CANRRG) FROM_FILE(CART00F) WITH_KEY(£BUKBO) RETURN_RRN(£CARTRRN)
37 | | V--LEAVE IF(((£LOCKRIS <> "ER") And (£LOCKRIS <> *BLANK)) Or (£io$sts <> "OK"))
38 | | |
39 | | | £LOCK.um_lock P_LOCKMULTIPLE(True) P_USER(*USER) P_FILE(CART00F) P_RRN(£CARTRRN) P_RESULT(£LOCKRIS) P_MESSAGE(£R_MES132) P_IDSESSIONE(*blank) P_FRAMEWORK(*blank) P_BUSINESSOBJ(*blank) P_INFO(£R_INFO)
40 | | --END_LOOP
41 | |
42 | | --IF (£LOCKRIS <> *BLANK)
43 | | | £LOCKRIS := *NULL
44 | | | --BEGIN_LOOP
45 | | | | FETCH FIELDS(£LOCKFTZ) FROM_FILE(RIGO00F) WITH_KEY(£CANROR £CANRRG) RETURN_RRN(£RIGORRN)
46 | | | V--LEAVE IF(((£LOCKRIS <> "ER") And (£LOCKRIS <> *BLANK)) Or (£io$sts <> "OK"))
47 | | | |
48 | | | | £LOCK.um_lock P_LOCKMULTIPLE(True) P_USER(*USER) P_FILE(RIGO00F) P_RRN(£RIGORRN) P_RESULT(£LOCKRIS) P_MESSAGE(£R_MES132) P_IDSESSIONE(*blank) P_FRAMEWORK(*blank) P_BUSINESSOBJ(*blank) P_INFO(£R_INFO)
49 | | | --END_LOOP
50 | | --ENDIF
51 | |
52 | --ENDSELECT
56 | £LOCK.um_unlockBatch P_USER(*USER) P_FILE(RIGO00F)
57 | £LOCK.um_unlockBatch P_USER(*USER) P_FILE(CART00F)