Creare oggetti transazionali COM+

di Bruno A. Zambetti, in COM & WebClass,

Tutti noi ci siamo trovati nella situazione di dover eseguire, nelle nostre applicazioni web, delle operazioni complesse sul database, composte cioè da più di una operazione elementare (SELECT, UPDATE, ecc.) in sequenza. Queste operazioni sono, inoltre, quasi sempre caratterizzate dalla necessità di rispettare le proprietà acide; per chi non ricordasse cosa sono le proprietà acide, senza entrare in richiami di teoria dei database limitiamoci a dire, con grossa approssimazione, che significa che quella sequenza di operazioni (di seguito "transazione") deve essere tutta eseguita, o tutta annullata.

La soluzione più banale che abbiamo imparato ad utilizzare è stata quella di aprire e chiudere una transazione tramite ADO. Questo si può agevolmente fare con il metodo "BeginTrans" dell'oggetto ADOB.Connection per l'apertura, e di metodi "CommitTrans" e "RollbackTrans" per la chiusura (rispettivamente con successo o fallimento delle operazioni comprese nella transazione).

Una soluzione alternativa al problema, frequentemente usata, è quella di scrivere una stored procedure che svolga la sequenza di operazioni richieste, ed utilizzare i comandi SQL del nostro DBMS per ottenere il medesimo risultato con una logica praticamente identica a quanto evidenziato per ADO.

Entrambe queste soluzioni sono perfettamente funzionanti, ma non sono troppo funzionali. Il motivo è presto detto: obbligano a scrivere tutto il codice necessario per ciascuna delle operazioni coinvolte nella transazione all'interno della procedura dove viene aperta e chiusa la transazione (o della specifica stored procedure). Non è quindi possibile delegare alcune operazioni ad altri metodi di altri oggetti, ma bisogna realizzare un sorgente monolitico. Come è ovvio, la possibilità di atomicizzare le operazioni in metodi ben specifici e circoscritti, ciascuno con un compito ben preciso, e, soprattutto per quelli che si occupano della manipolazione dei dati, elementare, è alla base della riutilizzabilità e mantenibilità delle nostre applicazioni. Il non poter mantenere questa struttura nelle operazioni transazionali sarebbe pertanto un limite piuttosto grosso e renderebbe l'intera architettura COM+ ed il paradigma DNA un oggetto più teorico che pratico. Dico sarebbe perché, ovviamente, la soluzione esiste, ed è costituita dal supporto alle transazioni offerto da COM+.

Comportamento dichiarativo

COM+ introduce il concetto del comportamento "dichiarativo" rispetto alle transazioni. Questo significa che non è la presenza o meno di determinati comandi all'interno del codice a far sì che le operazioni vengano eseguite in un contesto transazionale o meno, ma il valore assegnato ad alcuni attributi della classe che contiene la routine. In particolare, se guardiamo le proprietà di una classe VB6 (ambiente usato come riferimento per questo articolo, anche se COM+ chiaramente non è legato ad uno specifico linguaggio), possiamo notare la proprietà "MTSTransactionMode".

Questa proprietà indica quale è il comportamento della classe rispetto alle transazioni, e, pertanto, è il punto cruciale nella definizione della struttura delle nostre applicazioni transazionali.

I valori che questa proprietà può assumere sono:

  • notAnMTSObject: per compatibilità con i vecchi componenti. L'oggetto non è in grado di interagire con il runtime di COM+ per quanto riguarda le transazioni.
  • noTransactions: la classe non offre supporto alle transazioni, quindi tutte le operazioni in essa definite verranno sempre eseguite in maniera slegata dal resto, senza il contesto di una transazione.
  • usesTransaction: la classe può essere eseguita all'interno di una transazione (ed in questo caso si comporterà in maniera coerente alla transazione ed al resto degli oggetti coinvoli), ma non richiede che questo avvenga necessariamente.
  • requiresTransaction: la classe richiede di essere eseguita all'interno di un contesto transazionale e non può essere eseguita in altro modo.
  • requiresNewTransaction: la classe richiede di essere eseguita all'interno di un contesto transazionale, ed inoltre questo contesto non deve essere "ereditato" ma deve essere creato appositamente per questa classe.

Come si può vedere, il fatto che le operazioni eseguite da un certo metodo siano in contesto transazionale o meno non dipende più dall'uso di particolari comandi come il BeginTrans di ADO, ma diventa un parametro strutturale della nostra applicazione che viene definito a livello di progetto macroscopico.

Commit o Rollback?

Siccome il fatto di eseguire un commit o un rollback su una transazione non è chiaramente una scelta che può essere presa a livello di progetto, ma deve essere presa a run-time, esistono ovviamente dei comandi per indicare a COM+ come deve chiudere la transazione.

Questo comandi sono metodi dell'oggetto contesto, richiamabili semplicemente come GetObjectContext.setCommit e GetObjectContext.setAbort (attenzione ad impostare un riferimento alla typelibrary di COM+).

Chiamare uno di questi metodi indica all'ambiente di COM+ come deve chiudere la transazione in corso ed quindi finalizzare le operazioni sul database.

3 pagine in totale: 1 2 3
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti