Gestione delle transazioni con il .NET Framework 2.0

3 pagine in totale: <<Indietro 1 2 [3]

Un TransactionManager custom

Per poter creare un'alternativa è necessario capire quali sono le caratteristiche essenziali che il nostro sistema per l'accesso ai dati deve rispettare per poter rendere transazionale un insieme di operazioni.

Figura 2

Ogni classe che lavora sui dati presente nella nostra applicazione deve implementare un' interfaccia ITransactionable che sta ad indicare che la classe può essere sottoposta a transazione e che deve esporre una proprietà pubblica ExternalTransaction di tipo IDbTransaction. Per ogni operazione su database sarà quindi necessario controllare che questa proprietà sia stata istanziata e, nel caso non sia nulla, utilizzarla senza creare una nuova connessione.

If(ExternalTransaction == null)
{
  // Creo una nuova connessione.
}
else
{
  // L'oggetto non è nullo, quindi mi trovo in un contesto transazionale.
  // Non devo creare una nuova connessione,
  // ma utilizzare quella assegnata all'oggetto ExternalTransaction.
}

Oltre all'interfaccia abbiamo bisogno di definire un tipo TransactionManager che ci permetta di gestire più classi di accesso ai dati per le varie tipologie di oggetto (riprendendo l'esempio iniziale: Utenti, Ruoli, ecc.). Qualora la sorgente dati sia un database SQL Server, questa classe deve avere i seguenti campi privati:

  • private SqlConnection conn;
  • private SqlTransaction transaction;
  • private List<ITransactionable> coll;

e i seguenti metodi:

  • public void Add(ITransactionable transactionObject);
  • public void Remove(ITransactionable transactionObject);
  • public void StartTransaction();
  • public void Commit();
  • public void Rollback();
  • public void Close().

Il campo conn è la connessione al database (di tipo SqlConnection), transaction è l'oggetto transazionale che deve essere condiviso da tutte le operazioni (di tipo SqlTransaction) e coll è la collection di classi per l'accesso ai dati che implementano l'interfaccia ITransactionable.

Il metodo Add() non deve far altro che aggiungere una nuova classe di accesso ai dati alla collection, al contrario la funzione Remove() la deve eliminare. Il metodo StartTransaction() deve creare una nuova connessione alla sorgente dati e, una volta aperta, su di essa deve attivare la transazione e impostare per tutti gli elementi della collection coll la proprietà ExternalTransaction. I metodi Commit(), RollBack() e Close() richiamano i metodi corrispondenti degli oggetti interni dell'istanza di TransactionManager.

Se a tutto ciò aggiungiamo l'interfaccia IDisposable, possiamo utilizzare la classe TransactionManager come mostrato nel blocco di codice seguente:

using (TransactionManager manager = new TransactionManager())
{
  UserProvider usp = new UserProvider();
  RoleProvider rlp = new RoleProvider();
  ProfileProvider pfp = new ProfileProvider();

  Manager.Add(usp);
  Manager.Add(rlp);
  Manager.Add(pfp);

  manager.StartTransaction();

  try
  {
    usp.Update(user);
    rlp.Update(role);
    pfp.Update(profile);
    manager.Commit();
  }
  catch
  {
    manager.Rollback();
    throw;
  }
}

Analizzando questo blocco di codice, si può notare come il procedimento sia molto simile a quello discusso inizialmente per le transazioni ADO.NET, con l'unica differenza che ad ogni classe di accesso ai dati andiamo ad iniettare l'oggetto transazionale.

Ovviamente questo è solo un esempio di come si può implementare un TransactionManager custom, ma quando lo si fa, bisogna tener conto che la connessione è una sola e rimane aperta per tutta la durata delle operazioni su database.

Conclusioni

Quello presentato in questo articolo è un'insieme di soluzioni che si possono utilizzare per cercare di creare contesti transazionali condivisi tra oggetti. Sfruttando gli esempi indicati nell'articolo e il codice presente nel file allegato, è possibile creare la classe TransactionManager custom più adatta alle proprie esigenze. Per esempio, possiamo considerare l'idea di rendere la classe TransactionManager astratta rispetto al tipo di database utilizzando le interfacce IDbConnection e IDbTransaction in sostituzione di SqlConnection e SqlTransaction rispettivamente.

Approfondimenti

3 pagine in totale: <<Indietro 1 2 [3]

Attenzione: Questo articolo contiene un allegato

Contenuti dell'articolo

Commenti
Dai un voto a questo articolo, ci aiuterà a migliorare il nostro sito (1 è il voto minimo, 5 il massimo).

Per procedere al rating dell'articolo devi essere autenticato.

Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.


TUTORIALS
TOP TEN ARTICOLI
NOTIFICHE

Iscriviti alla nostra newsletter nuoviarticoli per ricevere e-mail le notifiche!

Indirizzo e-mail:
PROVIDER ASP.NET 2.0

Seleziona il database per avere il web.config pronto per Membership, Roles e Profile API.



IN EVIDENZA
MISC