2013-02-27 20 views
12

Secondo la primavera javadoc @Transactional(propagation = Propagation.SUPPORTS)Quando utilizzare Spring @Transactional (propagation = Propagation.SUPPORTS)?

sostenere una transazione corrente, eseguire non transazionale se nessuno esiste. Attributo di transazione analogo a EJB con lo stesso nome.

Sembra che io possa solo dichiarare metodi non transazionali ed essere appena finito con esso, quindi le mie domande sono.

  • Quali sono alcune situazioni in cui è necessaria la propagazione SUPPORTI?
  • Qual è il punto della propagazione dei supporti?

Qualcuno può dare un esempio/scenario del mondo reale in cui i SUPPORTI erano effettivamente utili?

+0

Heva un'occhiata a questa risposta: http: // stackoverflow.it/questions/6437828/spring-transactions-with-supports-propagation # 6437924 – GKislin

risposta

5

L'esempio più semplice che si possa pensare sarebbe un metodo che invia del contenuto a un server JMS. Se si è nel contesto di una transazione, si desidera che il messaggio sia accoppiato all'ambito della transazione. Ma se non c'è già una transazione in esecuzione, perché preoccuparsi di chiamare anche il server di transazione e avviarne uno solo per fare un messaggio one-off?

Ricordare che questi possono essere dichiarati su un'API e un'implementazione. Quindi, anche se non c'è molta differenza per il tuo caso d'uso tra metterlo lì e non mettere nulla lì, aggiunge ancora valore per un autore API per specificare quali operazioni sono in grado di essere incluse in una transazione, al contrario di operazioni che forse chiamano un sistema esterno che non partecipa alle transazioni.

Questo è ovviamente in un contesto JTA. La funzione in realtà non ha molto uso pratico in un sistema in cui le transazioni sono limitate alle transazioni del database fisico locale delle risorse.

+0

nell'esempio JMS fornito, se non esiste tx ma la sessione/produttore jms è condivisa, quindi il messaggio inviato come parte del TX. Immagino che un tx distribuito sia l'unico posto in cui i SUPPORTI possono essere utili. – ams

+0

Penso che possa ancora essere utile in un'impostazione non distribuita come marker API se si hanno istanze di NOT_SUPPORTED e si vuole differenziare. Ma hai ragione che per quanto riguarda l'implementazione non è molto diverso dal mettere niente lì se non lo sono. – Affe

3

Fa un buon paio con la bandiera readOnly=true transazionale su un'operazione di selezione, soprattutto quando viene utilizzato ORM:

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS) 
public Pojo findPojo(long pojoId) throws Exception { 
    return em.find(Pojo.class, pojoId); 
} 

In questo caso assicurarsi di non pagare al prezzo di creare una nuova transazione se ci non è già solo per eseguire un'operazione di selezione.

Anche se sei stato in quel processo di pensiero già si potrebbe anche prendere in considerazione l'aspetto fosso transazionale tutti insieme:

public Pojo findPojo(long pojoId) throws Exception { 
    return em.find(Pojo.class, pojoId); 
} 
+0

quindi ... Vale veramente la pena di mettere l'annotazione @Transactional per effettuare selezioni in un database locale attraverso un framework ORM (ad esempio MyBatis)? – aloplop85

+0

di "abbandonare l'aspetto Transazionale", equivale a usare @NotTransactional? –

+0

Se qualcosa non ha aspetti di transazione o è @NotTransactional e viene richiamato da una transazione, cosa succede? per esempio. se il metodo transazionale A scrive qualcosa nel DB, allora chiama il metodo NotTransactional be, che scrive anche qualcosa, quindi eiter A o B lanciano un'eccezione non controllata, che viene sottoposta a rollback? –

0

Secondo questo emette Improve performance with Propagation.SUPPORTS for readOnly operation non si dovrebbe impostare un'operazione di sola lettura con Propagation.SUPPORTS:

Non è affatto chiaro che il cambiamento potrebbe effettivamente migliorare le prestazioni. Ci sono molti aspetti in questo. Il primo di questi è che l'articolo collegato è datato e incredibilmente imperfetto perché semplifica in modo aggressivo le cose. Posso entrare nei dettagli se vuoi, ma per ora lo lascerò. Ci sono un sacco di cose che giocano nelle prestazioni di esecuzione qui. Senza una transazione in corso, né il flag readOnly viene propagato al driver JDBC (che causerebbe un'ottimizzazione per molti database non applicati) né si applicheranno le ottimizzazioni nel codice di gestione delle risorse JPA di Spring come esplicitamente disattivando il flushing, che - se applicato - può migliorare notevolmente le prestazioni nel caso in cui si leggano molti dati.

Problemi correlati