Table of Contents

GlobalDataManager

Descor.DataManager.GlobalDataManager — il motore condiviso di accesso dati (cm) su cui poggiano tutte le DAL del verticale RequestCenter. Gestisce connessione Oracle, transazioni con IsolationLevel, esecuzione di stored procedure per nome e materializzazione in DataSet/IDataReader. Classe di istanza IDisposable, provider-agnostic via DbProviderFactory. Classificazione: VERIFIED.

Reference generata: rinviataDataManagerXNET compila (net8) ma docfx metadata fallisce con BC30002 (System.Data). Questa è pertanto la pagina concettuale di riferimento (spec §27).

Scopo

Fornire alle DAL un'unica astrazione per: aprire/chiudere la connessione Oracle, aprire/chiudere transazioni, eseguire stored procedure passando nome + DbParameter, e leggere i risultati come IDataReader/DataSet/DataTable, senza che la DAL conosca il provider concreto né gestisca il OracleConnection inline. [SUPPORTED]

Namespace e progetto

  • Nome pienamente qualificato: Descor.DataManager.GlobalDataManager (da RootNamespace; nessun blocco Namespace esplicito).
  • Progetto: DataManager (net48) / DataManagerXNET (net8, re-link). Vedi project-DataManager.md. [VERIFIED]

Responsabilità

  • Ciclo di vita della connessione (Open/Close/CloseIfNeeded/Reset/Dispose).
  • Transazioni (BeginTransaction/CommitTransaction/RollbackTransaction, InTransaction).
  • Esecuzione comandi (ExecuteNonQuery, ExecuteReader, ExecuteDbReader, ExecuteScalar, ExecuteInt32/Int64ReturnQuery).
  • Materializzazione (Fill, GetTable, GetDataSet).
  • Factory di comando/parametro/adapter (CreateCommand, CreateParameter, CreateReturn*Parameter, CreateDataAdapter).
  • Propagazione dei parametri di sessione DB (DbSessionParams -> SET_CONTEXT_VALUE). [VERIFIED]

Perché esiste

UNKNOWN — la motivazione storica/di business non è documentata nelle fonti. Tecnicamente funge da wrapper ADO.NET provider-agnostic condiviso; non si inferisce oltre.

Contratto pubblico

Costruttori:

  • New(providerName As String, connectionString As String) — registra/risolve il DbProviderFactory e memorizza la connection string (la connessione viene creata lazy in Initialize).
  • New(providerName As String, serverConnection As IDbConnection) — usa una connessione già esistente.

Proprietà: DbSessionParams (R/W), Connection (RO, lazy-init), Transaction (RO), InTransaction (RO), DefaultCommandType (R/W; impostarla marca _commandTypeSpecified).

Metodi principali documentati sotto: Open, Close, BeginTransaction, CommitTransaction, RollbackTransaction, ExecuteReader, ExecuteNonQuery, Fill. Altri: ExecuteScalar, ExecuteDbReader, ExecuteInt32/Int64ReturnQuery, GetTable, GetDataSet, CreateCommand, CreateParameter, CreateReturn*Parameter, CreateDataAdapter, Reset, CloseIfNeeded, Dispose. [VERIFIED]

Nota di nomenclatura: i metodi di transazione sono BeginTransaction/CommitTransaction/RollbackTransaction; il pattern Begin()/Commit()/Rollback() citato in FLOW-REQ-001 fa capo al wrapper RequestCenter.Transaction, che internamente delega a questi.

Implementazioni o classi derivate

Implements IDisposable. Reset è Overridable (nessuna derivata nota nel perimetro esaminato). [SUPPORTED]

Dipendenze

Solo astrazioni System.Data/System.Data.Common sotto net48. Sotto net8 (#If NET5_0_OR_GREATER) registra Oracle.ManagedDataAccess.Client.OracleClientFactory.Instance. NullFieldUtility è usato per convertire i valori di ritorno (es. ToInt32/ToInt64 dei return parameter). [VERIFIED]

Ciclo di vita

Istanza per-richiesta: per RequestCenter è creata/recuperata da Configuration.Settings.GetConnectionManager e cache in HttpContext.Current.Items("RCCONNECTIONMANAGER"). La connessione è aperta lazy al primo accesso a Connection (via Initialize). Dispose(True) chiama Close(Rollback) e poi _connection.Dispose(). [VERIFIED]

Stato interno

Campi privati: _disposed, _factory (Shared), _connectionString, _connection (IDbConnection), _transaction (IDbTransaction), _defaultCommandType, _commandTypeSpecified, _dbSessionParams. In Initialize, se DefaultCommandType non è stato esplicitamente impostato, viene forzato a CommandType.StoredProcedure. [VERIFIED]

Metodi principali

Public Function Open() As OpenConnectionResult

  • Scopo: aprire la connessione se chiusa e, opzionalmente, impostare il contesto di sessione DB.
  • Attese del chiamante: istanza non Disposed.
  • Parametri: nessuno.
  • Valore di ritorno: OpenConnectionResult.Opened se ha aperto la connessione, AlreadyOpen se era già aperta (usato da CloseIfNeeded per decidere se richiudere).
  • Precondizioni / Postcondizioni: se Disposed -> ObjectDisposedException. Post: connessione Open.
  • Eccezioni: ObjectDisposedException; in #If DEBUG un Catch ... Throw rilancia l'errore dell'impostazione contesto (il Finally è vuoto).
  • Validazione: stato connessione (ConnectionState.Closed).
  • Letture DB / Scritture DB: se DbSessionParams valorizzato, esegue la stored procedure SET_CONTEXT_VALUE con parametro PXMLSERIALIZEDDATA (coppie chiave/valore serializzate in XML) — imposta il contesto Oracle (es. DBUSERSESSION/DBSOURCESESSION).
  • Ambito transazionale: nessuno introdotto qui.
  • Side effect: apre la connessione fisica; può scrivere il contesto di sessione.
  • Prestazioni: una round-trip aggiuntiva a SET_CONTEXT_VALUE solo quando ci sono parametri di sessione.
  • Comportamento in errore e ripristino: in Release, l'eventuale eccezione di SET_CONTEXT_VALUE non è intercettata qui.
  • Classificazione: VERIFIED

Public Sub Close([pendingTransactionAction As PendingTransactionAction])

  • Scopo: chiudere la connessione, gestendo una transazione pendente.
  • Parametri: overload senza argomenti = Close(PendingTransactionAction.Rollback); l'overload esplicito accetta Commit/Rollback.
  • Precondizioni: se Disposed -> ObjectDisposedException.
  • Ambito transazionale: se _transaction IsNot Nothing, esegue CommitTransaction() o RollbackTransaction() secondo pendingTransactionAction, poi Connection.Close().
  • Side effect: chiude la connessione; può committare o annullare la transazione in corso. Default = Rollback (transazione non committata esplicitamente viene annullata).
  • Classificazione: VERIFIED

Public Sub BeginTransaction([isolationLevel As IsolationLevel])

  • Scopo: aprire una transazione sulla connessione (aprendola prima, se chiusa).
  • Parametri: overload senza argomenti (livello di isolamento di default del provider) e overload con IsolationLevel.
  • Precondizioni / Postcondizioni: se Disposed -> ObjectDisposedException. Se la connessione è chiusa, chiama Open() prima. Post: _transaction valorizzato, InTransaction = True.
  • Ambito transazionale: Connection.BeginTransaction(...). Non è previsto annidamento: una seconda chiamata sovrascrive _transaction senza chiudere la precedente. [SUPPORTED]
  • Side effect: può aprire la connessione.
  • Classificazione: VERIFIED

Public Sub CommitTransaction()

  • Scopo: committare la transazione corrente.
  • Precondizioni: se Disposed -> ObjectDisposedException. Agisce solo se InTransaction AndAlso Connection.State = Open.
  • Ambito transazionale: _transaction.Commit(), poi Dispose() e _transaction = Nothing.
  • Side effect: rende persistenti le scritture della transazione.
  • Comportamento in errore: se non c'è transazione aperta o la connessione non è aperta, è un no-op (nessuna eccezione).
  • Classificazione: VERIFIED

Public Sub RollbackTransaction()

  • Scopo: annullare la transazione corrente.
  • Precondizioni: come CommitTransaction (guardia InTransaction AndAlso Connection.State = Open).
  • Ambito transazionale: _transaction.Rollback(), poi Dispose() e _transaction = Nothing.
  • Side effect: scarta le scritture non committate.
  • Comportamento in errore: no-op se non in transazione / connessione non aperta.
  • Classificazione: VERIFIED

Public Function ExecuteReader(command As String[, parameters]) As IDataReader

  • Scopo: eseguire una stored procedure e restituire un IDataReader avanti-solo.
  • Attese del chiamante: command = nome package/procedure Oracle (es. "GETREQUEST"); i DbParameter sono creati con CreateParameter (incluso il refcursor OUT, convenzionalmente p_rc). Il chiamante è responsabile di consumare e chiudere il reader.
  • Parametri: overload per String (+ singolo DbParameter o ParamArray) e per IDbCommand.
  • Valore di ritorno: IDataReader.
  • Precondizioni: command Is Nothing -> ArgumentNullException.
  • Letture DB: esegue la procedure indicata come CommandType.StoredProcedure (default). Procedure del verticale in ../../../05-databases/REQUESTCENTER_TEST38/procedures.md.
  • Concorrenza / Ordinamento: se la connessione era chiusa all'ingresso usa CommandBehavior.CloseConnection (il reader chiuderà la connessione), altrimenti CommandBehavior.Default.
  • Side effect: apre la connessione se chiusa; Debug.WriteLine(command.CommandText) in Debug.
  • Comportamento in errore e ripristino: su eccezione chiama CloseIfNeeded(cnnState) e rilancia; il Finally fa sempre command.Dispose() (ma non chiude il reader/connessione in caso di successo — a carico del chiamante).
  • Prestazioni: streaming forward-only, no buffering (preferito per liste grandi rispetto a Fill).
  • Classificazione: VERIFIED

Public Function ExecuteNonQuery(command As String[, parameters]) As Integer

  • Scopo: eseguire una stored procedure senza result set (INSERT/UPDATE/DELETE o procedure con OUT scalari).
  • Attese del chiamante: command = nome procedure; parametri OUT (es. NEWREQUESTINDEX) letti dal chiamante dopo l'esecuzione.
  • Valore di ritorno: Integer (valore di DbCommand.ExecuteNonQuery).
  • Precondizioni: command Is Nothing -> ArgumentNullException.
  • Scritture DB: la procedure indicata (es. GESTREQUEST_T2.ADDREQUEST, GESTREQUEST.ADDDESCRIPTIONTOREQUEST, GESTREQUEST.ADDWORKFLOWINTERFACE) — vedi la DAL in ../RequestCenter/class-RequestDAL.md.
  • Ambito transazionale: partecipa alla transazione corrente se aperta (il comando eredita _transaction tramite CreateCommand).
  • Side effect: apre la connessione se chiusa; Finally esegue command.Dispose() e CloseIfNeeded(cnnState) (chiude solo se questa chiamata l'aveva aperta).
  • Comportamento in errore: in #If DEBUG Catch ... Throw; il Finally esegue comunque dispose/close.
  • Note: varianti ExecuteInt32ReturnQuery/ExecuteInt64ReturnQuery inseriscono un return parameter in posizione 0 e ne restituiscono il valore via NullFieldUtility.ToInt32/ToInt64(..., -1).
  • Classificazione: VERIFIED

Public Function Fill(dataSet As DataSet, command As String[, parameters]) As Integer

  • Scopo: eseguire una stored procedure e riempire un DataSet (materializzazione completa in memoria).
  • Attese del chiamante: fornire un DataSet da popolare; command = nome procedure; opzionale srcTable per l'overload che nomina la tabella di destinazione.
  • Valore di ritorno: Integer (righe caricate, da DbDataAdapter.Fill).
  • Letture DB: procedure indicata (es. cm.Fill(ds, "GETREQUEST", idrequestParam, p_rc)); refcursor mappato in DataTable.
  • Ambito transazionale: il comando eredita _transaction se presente (via CreateCommand).
  • Side effect: crea un DbDataAdapter (CreateDataAdapter), esegue Fill, poi command.Dispose() nel Finally. La gestione apertura/chiusura connessione è delegata all'adapter ADO.NET.
  • Prestazioni: carica l'intero result set in memoria — più costoso di ExecuteReader per volumi elevati; le DAL espongono spesso un gemello DataSet (Fill) e un gemello DReader (ExecuteReader) per lo stesso comando.
  • Comportamento in errore: Catch ... Throw con Finally che fa dispose del comando.
  • Note: l'overload statico con srcTable richiede un Common.DbDataAdapter, altrimenti NotSupportedException.
  • Classificazione: VERIFIED

Collaborazioni

  • Chiamato dalle DAL come cm (variabile locale ottenuta dal factory di configurazione). [VERIFIED]
  • CreateCommand collega il _transaction corrente al comando; CreateParameter/CreateReturn*Parameter producono DbParameter provider-neutri; NullFieldUtility converte i valori/ritorni nulli. [VERIFIED]

Accesso al database

Nessuna tabella toccata direttamente dalla classe (esegue le procedure che il chiamante nomina). Unica procedure invocata internamente: SET_CONTEXT_VALUE (impostazione contesto di sessione) in Open(). Vedi ../../../05-databases/REQUESTCENTER_TEST38/index.md e ../../../05-databases/crud-matrix.md. [VERIFIED]

Transazioni

Modello a transazione singola per istanza (_transaction), senza annidamento. Close/Dispose di default fanno Rollback di una transazione pendente. CommitTransaction/RollbackTransaction sono no-op se non c'è transazione aperta. IsolationLevel è supportato tramite l'overload di BeginTransaction. [VERIFIED]

Autorizzazione

Nessun controllo di autorizzazione nella classe. La propagazione di identità avviene, se configurata, tramite DbSessionParams/SET_CONTEXT_VALUE; l'autorizzazione applicativa è responsabilità dei layer superiori. [SUPPORTED]

Side effect

Apertura/chiusura connessioni fisiche, esecuzione di procedure Oracle, dispose di comandi e transazioni, eventuale scrittura del contesto di sessione. [VERIFIED]

Gestione degli errori

ObjectDisposedException sugli accessi post-dispose; ArgumentNullException su comando nullo. Blocchi Catch ... Throw condizionati a #If DEBUG in Open/ExecuteNonQuery/ExecuteScalar; ExecuteReader/ExecuteDbReader/Fill intercettano sempre per fare cleanup e rilanciano. Logging non implementato ('Todo: Loggare l'errore). [VERIFIED]

Thread safety

Non thread-safe. Lo stato di istanza (_connection, _transaction) non è sincronizzato; inoltre _factory è Shared e fissato al primo utilizzo nel processo. L'uso previsto è un'istanza per richiesta (cache in HttpContext.Current.Items). [INFERRED]

Considerazioni sulle prestazioni

  • ExecuteReader (forward-only, streaming) è preferibile a Fill/GetDataSet per grandi result set.
  • Open aggiunge una round-trip solo se DbSessionParams è valorizzato.
  • CloseIfNeeded evita di chiudere connessioni che il chiamante aveva già aperto (importante dentro una transazione multi-comando). [SUPPORTED]

Esempio di utilizzo

Pattern reale (verificato staticamente, non eseguito) — da RequestDAL.vb:

Dim cm As GlobalDataManager = Configuration.Settings.GetConnectionManager
Dim idrequestParam As DbParameter = cm.CreateParameter("PIDREQUEST", idRequest)
Dim p_rc As DbParameter = cm.CreateParameter("...")  ' refcursor OUT
Return cm.ExecuteReader("GETREQUEST", idrequestParam, p_rc)

[VERIFIED — RequestDAL.vb:52]

Test correlati

Nessun test automatico (0 progetti di test nel repo). Copertura non misurata. [VERIFIED]

Flussi correlati

Regole di business correlate

Limitazioni

  • Transazione singola non annidabile.
  • Provider fissato a livello di processo (Shared _factory).
  • Nessun logging degli errori.
  • Ciclo di vita del reader/connessione parzialmente a carico del chiamante. [SUPPORTED]

Debito tecnico

  • 'Todo: Loggare l'errore in Open().
  • Divergenza #If DEBUG nell'intercettazione delle eccezioni tra Debug e Release.
  • Reference DocFX rinviata (BC30002 in docfx metadata) — pagina concettuale. [SUPPORTED]

Evidenze

  • InfocadWeb/WebMachine/DataManager/GlobalDataManager.vb:9 (classe), :14-21 (campi, Shared _factory), :32-50 (costruttori), :63-98 (proprietà Connection/Transaction/InTransaction/DefaultCommandType), :104-131 (Open + SET_CONTEXT_VALUE/PXMLSERIALIZEDDATA), :133-149 (Close overloads, default Rollback), :155-169 (BeginTransaction +IsolationLevel), :171-189 (Commit/Rollback Transaction), :195-208 (Dispose), :214-245 (ExecuteNonQuery), :249-289 (ExecuteInt32/Int64ReturnQuery), :297-335 (ExecuteReader + CommandBehavior + Debug.WriteLine), :341-378 (ExecuteDbReader), :384-415 (ExecuteScalar), :423-487 (Fill), :495-563 (GetTable/GetDataSet), :574-588 (CloseIfNeeded/Initialize -> StoredProcedure), :592-614 (CreateCommand + eredita _transaction), :620-716 (CreateParameter/CreateReturn*), :722-730 (CreateDataAdapter).
  • InfocadWeb/WebMachine/DataManager/Enums.vb:2-10 (OpenConnectionResult, PendingTransactionAction).
  • InfocadWeb/WebMachine/DataManager/NullFieldUtility.vb:52-90 (ToInt32/ToInt64 usati dai return query).
  • InfocadWeb/WebMachine/RequestCenter/Configuration/Settings.vb:242-262 (GetConnectionManager, cache RCCONNECTIONMANAGER, DbSessionParams DBUSERSESSION/DBSOURCESESSION).
  • InfocadWeb/WebMachine/RequestCenter.DAL.OracleODP/RequestDAL.vb:31,52,646,667 (cm.Fill/cm.ExecuteReader), RequestDAL.vb:5054/5089 (addRequest -> GESTREQUEST_T2.ADDREQUEST/GESTREQUEST.ADDREQUESTWITHOUTPROTOCOL), ComplaintDAL.vb:17/CallTypeDAL.vb:17 (ottengono cm).
  • Metadati: DataManagerXNET.vbproj:26 (Oracle.ManagedDataAccess.Core 23.4.0); artefatto Assembly/net8.0/DataManagerXNET.dll presente; reference DocFX rinviata per BC30002 (System.Data) — dichiarazione dell'orchestratore, non riproducibile su questo host.