2014-12-10 13 views
10

Ho appena iniziato l'apprendimento Hibernate e Io uso il seguente modello (da documentation) per ogni transazione:Hibernate - Devo davvero eseguire il rollback della transazione di sola lettura fallita?

private Session session; 
private Transaction transaction; 

protected List selectAll(Class clazz) throws HibernateException { 
    List objects = null; 
    try { 
     session = MyHibernateHelper.getSessionFactory().openSession(); 
     transaction = session.beginTransaction(); 

     // SELECT ALL 
     objects = session.createCriteria(clazz).list(); 

     transaction.commit(); 
    } catch (HibernateException exc) { 
     if (transaction != null) transaction.rollback(); 
     throw exc; 
    } finally { 
     session.close(); 
    } 
    return objects; 
} 

posso accettare che ogni operazione deve essere avvolto in una transazione. Ma mi sembra strano e inutile il rollback select, nel caso in cui fallisca.
Penso di poter rimuovere in modo sicuro il blocco catch dall'esempio precedente. E da qualsiasi operazione di sola lettura. Ho ragione?

+5

dipende da come è stata effettuata la selezione. se invocassi la semantica di blocco, il rollback rilasciava quelle serrature. –

risposta

9

Considerare che Hibernate deve funzionare con tutti i tipi di database per tutti i tipi di situazioni. Quello che ti stanno dando nella loro documentazione è come usare Hibernate da qualsiasi database supportato. E cercano di supportare molti database. Alcuni di questi database potrebbero gestire la pulizia delle transazioni fallite senza richiedere un rollback esplicito, ma Hibernate vuole assicurarsi che copra tutti.

Considerate anche che avere una transazione di sola lettura fallita sarà estremamente raro nella vita reale. Una volta che avviene non ci sarà molto da fare per il rollback, ma quello che fa - rilasciando i blocchi come fa notare Marc B - non è qualcosa che si vuole saltare. Quindi quello che stai sostenendo è una ottimizzazione molto piccola (basata su quanto raramente viene esercitato quel percorso) che potrebbe avere conseguenze negative in alcune circostanze. Avere un lock non rilasciato è il tipo di cattiva conseguenza che non si manifesta fino a quando qualche altra transazione fallisce o si blocca, rendendo molto difficile rintracciare la causa. Il blocco che non viene rilasciato potrebbe causare deadlock, quindi l'impatto su prestazioni/disponibilità potrebbe essere disastroso. Anche questo sarebbe un problema da testare, se c'è un problema sarebbe probabilmente mancato fino a quando non ci sarà una crisi in un ambiente di produzione. Su più conti è il tipo di cosa che vuoi evitare.

Il problema più grande qui è che c'è molto codice boilerplate da includere per ogni transazione. Il mio suggerimento è quello di implementare alcuni metodi di utilità utilizzando callback o il pattern Command (vedere il libro di Bauer e King's Persistence di Java con Hibernate per gli esempi) o adottare un framework. C'è una discussione contro le strutture che oscurano i dettagli di implementazione e rendono l'apprendimento più difficile, ma hai già avuto l'esperienza di apprendimento di vedere come questi pezzi sono messi insieme. Esistono framework maturi come Seam o Spring che gestiranno ciò per te.

+0

Hai messo ordine nei miei pensieri. Grazie! È davvero una piccola (prematura?) Ottimizzazione. In mia difesa posso solo dire che volevo ridurre al minimo il codice della piastra della caldaia e arrivare alla verità. – naXa

1

Se si utilizza un framework o API o ciò che non è realmente sotto il proprio controllo, è necessario rispettare sempre la strategia di errore perché non si sa come funziona internamente. Possono esserci altre risorse da liberare.

+0

'session.close()' sembra un metodo per la pulizia. Ma ['transaction.rollback()'] (https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/Transaction.html#rollback%28%29) è un metodo per forzare le operazioni all'interno di una transazione per il rollback. Secondo me può essere utile nelle transazioni multi-operazione e nelle transazioni di scrittura. Ma non in una transazione atomica di sola lettura fallita. – naXa

+1

Forse vero, ma a mio parere è soprattutto vantaggioso seguire le raccomandazioni del produttore, anche quando sembra non essere necessario. – Joachim