Gestione esplicita delle transazioni

rated by 0 users
This post has 14 Replies | 4 Followers

Top 10 Partecipanti
Maschio
Post 268
Punteggio 4.907
petrux Posted: 07-01-2011 14.35

Ciao a tutti,

 

mi sto arrovellando su questo problema: ho un servizio a livello di service layer che orchestra una serie di chiamate a servizi di business che fanno le loro belle operazioni. Secondo voi di chi è la reponsabilità della gestione delle transazioni? Attualmente l'ho implementata nel service layer. Che ne dite?

Ragioniamoci! :-)


Ciao,

Giulio

Top 10 Partecipanti
Post 143
Punteggio 2.560

definisci i boundary...se intra process o cross-process/machine?

.m

  • | Punteggio Post: 20
Top 10 Partecipanti
Maschio
Post 268
Punteggio 4.907

Ciao Mauro,

 

la situazione è la più semplice possibile: un unico processo su una sola macchina (lo scope è quello di una richiesta http). 

 

Ciao e grazie,

Giulio

 

-- 

 

  • | Punteggio Post: 20
Top 10 Partecipanti
Post 143
Punteggio 2.560

io seguo questa regola:

il chiamante come vede questo set di operazioni? se dal suo punto di vista sono un set che ha senso solo in un contesto atomico è il chiamate che deve gestire la transazione, altrimenti lascio che ogni chiamato faccia un po' quello che vuole nel suo "orticello".

Tendo a evitare sempre come la peste le cose implicite e automatiche, quindi non te lo faccio vedere ma ci metto di nascosto una transazione intorno perchè la volta che devi cambiare questa logica o impazzisci per farlo o prorpio non lo puoi fare.

.m

  • | Punteggio Post: 20
Top 10 Partecipanti
Maschio
Post 268
Punteggio 4.907

 

Ciao Mauro,

 

> io seguo questa regola:

> il chiamante come vede questo set di operazioni? se dal suo punto di vista sono un set che ha senso solo in un contesto atomico è il chiamate che deve gestire la transazione, altrimenti lascio che ogni chiamato faccia un po' quello che vuole nel suo "orticello".

 

Nel mio caso è vera la prima ipotesi, cio il chiamante (classe del mio service layer) vede l'insieme di chiamate che orchestra al business layer come un set atomico. Però il lasciare che ogni classe di business faccia quello che vuole non può portare a delle ambiguità?

 

> Tendo a evitare sempre come la peste le cose implicite e automatiche, quindi non te lo faccio vedere ma ci metto di nascosto una transazione intorno perchè la volta che devi cambiare questa logica o impazzisci per farlo o prorpio non lo puoi fare.

 

tipo iniziare/finire la transazione con http request?

Ciao,
Giulio
-- 

 

 

 

 

 

Top 10 Partecipanti
Post 143
Punteggio 2.560

petrux:

Nel mio caso è vera la prima ipotesi, cio il chiamante (classe del mio service layer) vede l'insieme di chiamate che orchestra al business layer come un set atomico. Però il lasciare che ogni classe di business faccia quello che vuole non può portare a delle ambiguità?

si, direi proprio di, ma se dall'esterno non ti aspetti/serve un comportamento atomico che ti frega?

petrux:

tipo iniziare/finire la transazione con http request?

è sicuramente una soluzione ma mi pongo questo quesito: all'interno del ciclo della richiesta http hai ad esempio 6 operazioni che sono atomiche a coppie, la domanda è ha senso che il fallimento della "quarta" sia causa del rollback anche delle prime 2? Oppure hai delle operazioni che non vuoi assolutamente che partecipino alla transazione.

.m

  • | Punteggio Post: 35
Top 10 Partecipanti
Maschio
Post 243
Punteggio 3.383

Io spesso uso una transaction per request, chiaramente perchè non ho mai la necessità di gestire una situazione come quella che dice mauro, essenzialmente quando ho un postback su una pagina mi attendo che sia transanzionale tutto. Però concordo con Mauro che questo non risolve assolutamente il problema in cui ho più operazioni in un unica richiesta e la transazionalità è a gruppi.

La cosa migliore è comunque quella di tenere il tutto staccato dai servizi / repository in modo che comunque dall'esterno vengqa deciso quando aprire / committare / rolbackare una transazione.

Alk.

  • | Punteggio Post: 5
Top 25 Partecipanti
Maschio
Post 6
Punteggio 105

In ottica DDD il contesto transazionale dovrebbe essere ben delineato all'interno degli aggregate root. Se tutte le operazioni di business che il service layer veicola devono essere "unite" in un'unica transazione è molto probabile che si stia operando su unico aggregato.

Qualora invece, come dice Mauro, le operazioni sono "transazionabili" a coppie (o a subset) gli aggregati sono più d'uno e, per me, è preferibile farli comunicare con degli eventi di dominio. In questo modo tutto ciò che deve rimanere atomico, rimane atomico (ed è garantito dall'aggregate root)...ma nulla più.

In contesti "enterprise" (scusa il parolone, che non vuole dire nulla, ma non so come descrivere un certo tipo di progetti che hanno una forte componente di behavior) il colloquio tra aggregati differenti tramite i domain events può appoggiarsi su un sistema ESB che garantisce la transazionalità anche degli eventi stessi garantendo un alto livello di "reliability".

Ciao

melkio

melkio

Blog: http://blog.codiceplastico.com/melkio
Twitter: http://twitter.com/amelchiori 

  • | Punteggio Post: 20
Top 10 Partecipanti
Maschio
Post 243
Punteggio 3.383

Interessantissima considerazione. Diciamo che in generale potrebbe essere anche vero, ma non amo che siano gli aggregati a gestire le transazioni. Mi spiego meglio: un aggregato è responsabile degli invarianti che rappresenta, ma non vorrei che fosse a conoscenza di un concetto relativo alla persistenza.

Potrei inoltre avere una situazione in cui io interagisco con più aggregate root per svolgere una operazione, e voglio che comunque tutto sia transazionale. Gestire le transazioni con i domain events mi pare complicato, ma forse mi sbaglio :). Questa però è una di quelle discussioni che andrebbero fatte a voce davanti ad una bella fiorentina :).

alk.

  • | Punteggio Post: 35
Top 10 Partecipanti
Post 143
Punteggio 2.560

sbaglio o quoalcuno ha parlato di fiorentina? :-)

.m

  • | Punteggio Post: 20
Top 10 Partecipanti
Maschio
Post 243
Punteggio 3.383
A Senigallia, possiamo mangiare il bisonte, Lorenzo può confermare :D
  • | Punteggio Post: 5
Top 25 Partecipanti
Maschio
Post 67
Punteggio 1.440

premessa: hai parlato di "Service Layer", che è l'analogo (per stessa ammissione dell'autore: http://martinfowler.com/bliki/AnemicDomainModel.html) nel "gergo Fowler" dell'Application Layer nel "gergo Evans".

Posta questa premessa, che contestualizza la discussione, possiamo affermare che ogni servizio rappresenta un caso d'uso, ergo è il "depositario" della conoscenza del processo. E' quindi il servizio a sapere cosa debba essere transazionale e cosa no, quindi è proprio nel servizio che implementerai la gestione della transazione. In alternativa, non dire "Service Layer": cambiando il contesto, cambiano le soluzioni :-)

 

.A

Top 10 Partecipanti
Maschio
Post 243
Punteggio 3.383

Concordo, giusta e doverosa precisazione. Anche io mi trovo nella stessa situazione, ogni servizio mi espone solitamente un caso d'uso che spesso si mappa con la UI. Spesso ho alcuni servizio di più.. diciamo... "basso livello", ho poi ad esempio un paio di applicazioni ed ogniuna ha un WCF Service dedicato e questo è concettualmente nell'application layer e mi espongono un "Transaction Script" alla UI.

In questo caso ogni chiamata al servizio è una transazione gestita con AOP :).

Alk.

  • | Punteggio Post: 5
Top 25 Partecipanti
Maschio
Post 6
Punteggio 105

Mi sono spiegato male: l'aggregate root garantisce che il/i behavior/s siano eseguiti in modo "atomico" dando la certezza di non portare l'aggregato stesso in uno stato inconsistente. La transazione "relazionale" è un concetto che non è direttamente veicolato dal DDD...è il solito problema del database :-)

Comunque, anche se più volte ho implementato anch'io la gestione transazionale tramite AOP, questo modus-operandi mi lascia sempre una strana sensazione di poca leggibilità. Non sono del tutto convinto che la gestione della transazione sia così ortogonale al service layer e quindi preferisco/preferirei che fosse più esplicito aumentando la "descrittività" del codice.

Comunque la fiorentina ci sta :-)

melkio

Blog: http://blog.codiceplastico.com/melkio
Twitter: http://twitter.com/amelchiori 

  • | Punteggio Post: 20
Top 10 Partecipanti
Maschio
Post 243
Punteggio 3.383

Le transazioni sono sempre oltremodo complesse :(, e quando sono innestate è l'inferno, ti faccio un caso pratico.

Inizio la transazione esterna.

   faccio delle cose

       inizio una transazione interna

          Faccio alter cose, poi mi accorgo che ci sta qualche cosa che non va

      rollbacko la transazione per annullare tutto quello che può essere stato fatto.

      voglio proseguire con altre azioni nella transazione pricnipale, riflettendo il fatto che "ho provato" a fare qualche cosa ma è andata male.

In questo caso ad esempio anche le entità debbono essere transazionali, ovvero quando io rollbacko la transazione del DB, anche le entità debbono automaticamente rollbackare allo stato pretransazione, non posso più usare la session di nhibernate... uffff è complesso, per cui concordo al 100% che ci sia una sensazione di poca leggibilità. :)

CAlcola quanto ti ci vuole ad arrivare a Senigallia, ed organizziamo :) per la fiorentina (ho un posto veramente doc). Se invece soffrite molto il caldo, ci sta la grigliata in baita alle pendici del monte catria, dove è freddo praticamente sempre :D

Alk.

  • | Punteggio Post: 5
Precedente | Successivo
Pagina 1 di 1 (15 elementi) | RSS
Powered by Community Server (Commercial Edition), by Telligent Systems