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.

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
- Classe System.Data.Common.DbTransaction
- Classe System.Data.SqlClient.SqlTransaction
- Namespace System.Transactions
- Enumerazione System.Transactions.TransactionScopeOption
- Implementazione di una transazione implicita mediante TransactionScope
3 pagine in totale: <<Indietro 1 2 [3]
Attenzione: Questo articolo contiene un allegato
Contenuti dell'articolo
- Galleria fotografica dinamica con ASP.NET AJAX
- Usare Search come un servizio nei tuoi siti e nei tuoi client
- Mappe nel tuo sito con Virtual Earth
- Integrare Windows Live ID, Contacts e Presence API nelle tue applicazioni
- Introduzione ai cloud based service con Windows Live Services
- Realizzare un custom extender AJAX con ASP.NET 3.5
- Tracciare le modifiche ai dati e allineare i datawarehouse con il Change Data Capture in SQL Server 2008
- Le nuove caratteristiche di IIS 7.0 per sviluppatori e sistemisti
Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.






Difficoltà
Utilità
Stampa
Download


10annidi.ASPItalia.com: iscriviti alla competizione e vinci fantastici premi ogni mese!