2010-11-13 24 views
23

Giusto per capire il funzionamento delle transazioni Spring, desidero sapere cosa succede nel seguente caso in cui un metodo contrassegnato come @Transactional chiama un altro metodo contrassegnato come @Transactional.Comprendere le transazioni Spring - Cosa succede quando un metodo transazionale chiama un altro metodo transazionale?

Si supponga che la configurazione utilizzi tutte le impostazioni predefinite.

@Service("myService") 
@Transactional 
public MyService{ 
    public void myServiceMethod(){ 
     myDAO.getSomeDBObjects(); 
    } 
} 

@Repository("myDAO") 
@Transactional 
public MyDAOWithUsesBeyondMyService{ 
    public void getSomeDBObjects(){...} 
} 

Ora, se dovessi entrare MyService.myServiceMethod() sarebbe chiaramente avviare una transazione. Quindi, dopo aver eseguito il drill su myDAO.getSomeDBObjects(), cosa accadrebbe? Il fatto che una transazione sia già esistente non causa la nascita di nuove transazioni o sto creando due transazioni qui?

La documentazione (citata sotto) su Propagation sembra coprire questo, ma vorrei verificare la mia comprensione, era un po 'troppo per il mio cervello vergine di comprendere tutto in una volta.

Propagazione: in genere, tutto il codice eseguito all'interno di un ambito di transazione verrà eseguito in tale operazione. Tuttavia, si ha la possibilità di specificare il comportamento nel caso in cui un metodo transazionale venga eseguito quando esiste già un contesto di transazione. Ad esempio, il codice può continuare a essere in esecuzione nella transazione esistente (il caso comune ); oppure è possibile sospendere la transazione esistente e creare una nuova transazione . Spring offre tutte le opzioni di propagazione della transazione familiari da EJB CMT. Per leggere la semantica della propagazione della transazione in primavera, vedere la Sezione 10.5.7, "Propagazione della transazione".

risposta

33

due risposte:

a) non lo fanno. Utilizzare @Transactional nel livello di servizio o nel livello dao, ma non entrambi (il livello di servizio è la scelta usuale, poiché probabilmente si desidera una transazione per metodo di servizio)

b) se lo si fa, ciò che accade dipende dallo propagation attributo dell'annotazione @Transactional ed è descritto in questa sezione: 10.5.7 Transaction propagation. Fondamentalmente: PROPAGATION_REQUIRED significa che la stessa transazione verrà utilizzata per entrambi i metodi, mentre PROPAGATION_REQUIRES_NEW avvia una nuova transazione.

Circa i tuoi commenti:

Naturalmente ho continuato a leggere e si rese conto che, come sto usando i proxy, questo secondo metodo non verrà gestito dalla procura transazionale, quindi è come tutti gli altri chiamata al metodo.

Questo non è vero nella vostra situazione (solo se entrambi i metodi erano all'interno della stessa classe).

Se un chicco ha metodi a e b e a chiamate b, quindi b è chiamato il metodo effettivo, non il proxy, perché è chiamato dall'interno del proxy (un fagiolo non sa che è proxied al mondo esterno).

proxy  bean 
a() --> a() 
      | 
      V 
b() --> b() 

Nella tua situazione, tuttavia, un servizio avrebbe un oggetto dao iniettato, che sarebbe un proxy stesso, in modo da dovreste avere una situazione come questa:

  proxy  bean 
service a() --> a() 
         | 
      /---------/ 
      |     
      V 
dao  b() --> b() 
+0

Grazie, sì, non ho intenzione di farlo, ma la domanda mi è venuta in mente quando ho capito che avevo dichiarato @Transactional a livello di classe di servizio, e un metodo del servizio stava chiamando un altro metodo del servizio (entrambi transazionale). Naturalmente ho continuato a leggere e mi sono reso conto che, poiché sto usando i proxy, questo secondo metodo non sarà gestito dal proxy transazionale, quindi è come qualsiasi altra chiamata al metodo (è sufficiente per confondere un cervello appena iniziato). :) Ma mi ha reso abbastanza curioso da assicurarmi di aver compreso i dettagli di come tutto funziona, l'hai chiarito bene per me. Grazie! –

+0

@David Penso che tu abbia frainteso un po 'il concetto di proxy. Leggi il mio aggiornamento. –

+0

Hai assolutamente ragione, il mio commento era in errore (in realtà ho scambiato le ipotesi senza dirlo), ma capisco cosa stai dicendo, e dopo tutto questo penso che il tutto sia ben radicato nella mia testa ora. Grazie per l'aggiornamento e gli ottimi diagrammi, sono sicuro che molti altri lo troveranno utile nelle loro ricerche in futuro! –

Problemi correlati