Salva ogni 5 minuti

,

Ma effettivamente quando le nostre modifiche vengono salvate sul database?

Stavo facendo formazione ad un ragazzo che inizia a muoversi ora su Business Central e gli stavo spiegando le basi di inserimento e modifica dati sul database. Mentre lo facevo mi sono reso conto che, nel corso degli anni, si sono accumulati n livelli di complessità che hanno reso il salvataggio di un dato non esattamente una operazione che avviene in un solo punto e che, volendo tenere conto anche degli eventi sottoscrivibili, la risposta può essere molto articolata.

Perciò, visto che mi era stato chiesto di buttare giù due righe per il blog ho pensato che potesse essere un argomento utile da ripassare.
Per prima cosa va fatta una importante distinzione nell’affrontare l’argomento ovvero di quale versione di Business Central si stia parlando e che feature siano attive nella gestione funzionalità.

Nel caro vecchio Navision e nelle prime versioni di Business Central, infatti il dato veniva salvato all’uscita dalla pagina dove il record veniva modificato o allo spostamento su un record successivo. Per qualcosa come due decenni questa è stata una regola sacra di cui tenere conto. Tutti gli eventi legati alla modifica di un scattavano solo in quel momento.

Nell’ottobre del 2022 però, Microsoft ha introdotto un cambiamento radicale nella gestione del salvataggio dati su Business Central, una funzionalità che ha chiamato SAVE AS YOU TYPE.

Business Central salva immediatamente le modifiche ai singoli campi non appena si esce dal campo o si imposta lo stato attivo su un altro elemento della pagina, invece di salvare solo alla chiusura della pagina. Le modifiche vengono salvate nel database senza alcun impatto evidente sulle prestazioni.

Questa modifica ovviamente, ha stravolto dei flussi che erano attivi da anni e anni per moltissimi flussi ed ha avuto un impatto così dirompente che Microsoft ha dovuto rendere disabilitabile la funzionalità e addirittura non renderla attiva di default sugli ambienti preesistenti onde evitare problematiche non previste.

Aggiornamento: questa funzionalità viene controllata in Gestione funzionalità e potrebbe essere necessaria l’attivazione da parte dell’amministratore, poiché è disattivata per impostazione predefinita in tutti gli ambienti aggiornati al secondo ciclo di rilascio del 2022. In questo modo amministratori e partner hanno un maggiore controllo.


Tenendo a mente questa variazione, per spiegare bene il flusso di modifica di un dato ho creato una tabella molto semplice:

Un intero campo come chiave primaria e tre campi A B e C con il solo scopo di verificare il comportamento su campi multipli.

Quando si crea una nuova tabella c’è subito a disposizione un trigger di modifica:

Il codice all’intero di questa funzionalità viene eseguito solo se la modifica viene effettuata da una pagina o se il comando MODIFY viene eseguito con il parametro TRUE.

La tabella è estendibile e nella sua estensione sono definibili tre trigger aggiuntivi:

Creando una pagina editabile associata alla tabella stessa c’è la possibilità di avere un trigger:

il codice all’interno di questo trigger viene eseguito solo se la modifica è effettuata dall’interno di quella pagina.

Se la pagina è estendibile nella sua estensione è possibile aggiungere un ulteriore trigger:

il codice all’interno di questo trigger viene eseguito solo se la modifica è effettuata dall’interno di quella pagina.

È poi possibile sottoscrivere da una codeunit gli eventi onbefore:

e onafter:

È interessante notare come questi due eventi vengano cmq sempre eseguiti ma uno dei parametri (runtrigger) sia legato appunto al valore passato al comando MODIFY.

È poi possibile sottoscrivere l’evento modify sulla pagina specifica associata al record:

il codice in questo evento viene eseguito solo se la modifica avviene dall’interno della pagina.
A questi eventi sottoscritti si possono teoricamente aggiungere altri due eventi pubblicati in quella che era la vecchia codeunit 1 è che ora è stata scorporata in più codeunit.

In particolare, nella GlobalTriggerManagement si possono sottoscrivere:

Perchè questi due trigger scattino è necessario che la tabella da analizzare sia stata definita nell’evento OnAfterGetDatabaseTableTriggerSetup sempre nella global triggermanagement e va inoltre notato che, dato che il parametro è un generico recref, TUTTI i record configurati in questo modo eseguiranno il codice all’interno ed è quindi auspicabile che il codice verifichi chi è il mittente effettivo dell’esecuzione dell’operazione.

A parità di evento sottoscritto non c’è possibilità di sapere quale sia l’ordine di esecuzione, ma è invece molto chiara la sequenzialità con cui questi eventi vengono triggerati.


Supponiamo di avere una versione di Business Central dove la funzionalità SAVE AS YOU TYPE è disabilitata.

Dato un record

Supponendo di modificarlo dalla pagina in cui abbiamo inserito il trigger facendolo diventare:

La sequenza di esecuzione è la seguente:

Prima viene eseguito il codice sulla pagina, quello nella page extension e quello nella sottoscrizione dell’evento della pagina. Una volta finita la parte relativa alla gui si passa al codice legato alla tabella.

Scattano in sequenza i due eventi onbefore, prima sull’oggetto e poi sulla estensione.

Gli eventi modify prima sull’oggetto e poi sull’estensione.

Solo a questo punto il sistema sta per effettuare la modifica e viene scatenato l’evento globale.

Infine vengono scatenati i due eventi onafter: prima l’estensione e poi sulla tabella, in ordine opposto rispetto a quanto avviene sull’onbefore.

Supponendo di modificare tutti i 3 campi senza lasciare il record o uscire dalla pagina i trigger in esecuzione sarebbero i seguenti:

In pratica il flusso di modifica viene eseguito una sola volta.

Attivando la funzionalità SAVE AS YOU TYPE il sistema si comporta in modo diverso.
Se per la modifica di un solo campo non sembra esserci differenza:

Modificando i tre campi, pur senza uscire dal record o abbandonare la pagina:

L’intera sequenza di trigger viene eseguita per ogni singolo campo. Questo, ovviamente, ha un impatto sostanziale e bisogna tenerne conto in fase di scrittura del codice.

Se per esempio in fase di modifica di una testata ordine si vuole eseguire una operazione di ricalcolo di un valore sulle righe non va messo del codice in uno qualsiasi di questi trigger senza tenere conto di questa esecuzione multipla.

Oppure, se non è possibile adattare il codice a questa modalità di gestione del dato, in attesa che Microsoft aggiunga un evento che sostituisca la vecchia gestione, disabilitare la funzionalità.
Non c’è una risposta corretta per tutte le situazioni perché l’adeguamento non è immediato.


Marco Costanza
Senior Software Developer