2012-06-15 11 views
39

Cosa dovrei preferire quando aggiorno il database? Quali sono i pro & contro con entrambi i metodi e quando devo usare l'uno o l'altro?Entitymanager.flush() VS EntityManager.getTransaction(). Commit - Cosa dovrei preferire?

public void disemployEmployee(Integer employeeId, Date endDate) { 
    Employee employee = (Employee)em.find("Employee", employeeId); 
    employee.getPeriod().setEndDate(endDate); 
    em.flush(); 
} 

public void disemployEmployee(Integer employeeId, Date endDate) { 
    Employee employee = (Employee)em.find("Employee", employeeId); 
    em.getTransaction().begin(); 
    employee.getPeriod().setEndDate(endDate); 
    em.getTransaction().commit(); 
} 

risposta

42

Nel vostro primo esempio, le modifiche ai dati si riflettono nel database dopo aver incontrato a filo, ma è ancora nella transazione.

Ma nel secondo esempio, si sta eseguendo la transazione immediatamente. Pertanto le modifiche vengono apportate alla transazione & del database che termina anche lì.

A volte, lo svuotamento può essere utile per mantenere i dati tra la transazione in corso & e infine confermare le modifiche successivamente. In questo modo è anche possibile eseguire il rollback delle modifiche precedenti se si verifica qualche problema in seguito, come per l'inserimento/l'aggiornamento in batch.

+8

Nel primo esempio non c'è nessuna transazione, quindi c'è un'eccezione generata a flush(). – DataNucleus

+1

@DataNucleus Penso che in CMT, non dobbiamo avviare/terminare la transazione manualmente. –

+2

sicuro, ma lui è in CMT? nel suo altro esempio inizia il txn, quindi questa è l'unica ipotesi che posso rendere – DataNucleus

14

avete letto il javadoc per filo e si impegnano e sanno che colore è solo per l'uso all'interno di una transazione? Lavora (ma non commette), mentre commit commette dati (ovviamente). Sono distinti; non c'è nessuna "preferenza" da avere. Il primo esempio è errato e dovrebbe comportare un'eccezione sulla chiamata flush (TransactionRequiredException)

+1

Che cosa posso fare con flush() che non posso fare a meno di utilizzare flush()? – Rox

+1

Flush inserisce i dati nell'archivio dati e senza di essi i dati non sono presenti, pertanto le query possono restituire dati obsoleti. Forse leggi la specifica JPA su flush() – DataNucleus

+2

Bene, tutto ciò che l'API dice su flush() è "Sincronizza il contesto di persistenza con il database sottostante" e non l'ho mai usato prima, ma le mie transazioni mettono ancora i dati nel database quando chiamano ' EntityManager.getTransaction.commit() '. E non ho chiamato EntityManager.flush()! Quindi non riesco a capire l'uso di flush() quando puoi fare tutto ciò che fa anche senza. – Rox

3

Entrambi i campioni di codice non mantengono o fondono lo stato dell'entità da scrivere nel DB.

Non ritengo opportuno confrontare EntityManager.flush() e EnityManager.EntityTransaction.commit().

flush() DEVE essere incluso in un contesto di transazione e non è necessario farlo esplicitamente, a meno che non sia necessario (in rari casi), quando EntityTransaction.commit() lo fa per te.

consultare questo link Is it necessary to call a flush() (JPA interface) in this situation?

consultare questo link Question about flushing with JPA before a query is called per uno scenario di usare flush()

+0

Come ho chiesto a DataNucleus: Cosa posso fare con flush() che non posso fare senza usarlo? – Rox

+0

Aggiornato la mia risposta. Spero che il link risponda alla tua domanda. –

+0

@AhamedMustafaM 'Entrambi gli esempi di codice non persistono o uniscono lo stato dell'entità da scrivere nel DB. No, se l'entità è gestita, le modifiche verranno sincronizzate nel database in modo implicito. –

0

Vorrei andare per transazione gestita contenitore quando possibile. Le transazioni gestite da Bean di solito richiedono un numero significativamente maggiore di codice, a causa delle possibilità di Eccezione. Inoltre, è più soggetto a errori (rollback, gestione delle risorse).

Detto questo, vorrei utilizzare uno svuotamento dopo il commit in modalità di gestione del contenitore. In questo modo posso rilevare PersistenceExceptions nel mio modulo di archiviazione e convertirlo in un Eccezione più significativo per il mio modulo case use. Questo perché non voglio gestire eccezioni specifiche dello storage qui, perché potrei scambiare il modulo di archiviazione con qualcosa che non usa JPA ... che non mi è mai successo :)

0

Penso che la parte mancante sia , flush() basta aggiungere alle origini dati per essere pronti a commettere, fornisce gli ID effettivi ma non persistono per impostazione predefinita.

Quindi, se avete bisogno di flush() per lavorare come commit() è necessario impostare la modalità a filo Conferma nella EntityManager da:

void setFlushMode(FlushModeType flushMode) 
Set the flush mode that applies to all objects contained in the persistence context. 

noti che FlushModeType è un enum che ha questi due valori:

FlushModeType AUTO (predefinito) Flushing che si verifica durante l'esecuzione della query. Da: JPA 1.0 FlushModeType COMMIT Flush che si verifica alla transazione commit. Il provider può scaricare altre volte, ma non è necessario. dal: JPA 1,0

Spero che questo aiuto

Problemi correlati