2013-10-30 18 views

risposta

20

withTransaction è un po 'hackerato perché consente di eseguire operazioni transazionali ovunque, ma è meglio separare le preoccupazioni e svolgere il lavoro in un servizio transazionale. Per impostazione predefinita, un servizio è transazionale a meno che non si aggiunga static transactional = false e sia possibile perfezionarlo a livello di classe e/o metodo con l'annotazione @Transactional. Si dovrebbe andare bene solo mettendo il codice in un metodo di servizio senza utilizzare withTransaction o withSession.

withSession è un modo conveniente per accedere all'Hibernate corrente Session (in genere quello registrato dall'intercettore OpenSessionInView). Se si desidera cancellare la sessione o eseguire altri lavori non esposti da GORM, questo è un modo per accedervi senza accedere allo sessionFactory o ai supporti locali del thread utilizzati da Spring.

Un uso un po 'valida di withTransaction al di fuori di un metodo di servizio transazionale è quello di associare un Hibernate Session quando si è al di fuori di una richiesta di controllo (vale a dire quando non c'è auto-creato Session). withTransaction inizierà una transazione e creerà un Session se necessario e lo manterrà aperto per la durata della chiusura. Quindi puoi usarlo per evitare eccezioni di caricamento lento. Abbiamo bisogno di un altro modo per farlo senza il sovraccarico di una transazione, per quei casi in cui stai solo leggendo dal database e non hai bisogno di scritture transazionali. Ma per ora, questo approccio funziona. Tuttavia, se si eseguono scritture di database, spostare il codice su un metodo di servizio.

+0

Grazie Burt. Stavo registrando i record e ho scoperto che avevo bisogno della scorciatoia 'withSession', come chiamata' sessionFactory.getCurrentSession(). Clear() 'stava diventando tedioso. –

+0

Questa risposta non è strettamente vera. Esistono molti casi in cui si desidera eseguire il rollback in un servizio senza generare un'eccezione per il chiamante. In questo caso, l'unica opzione è usare con Transaction. –

+4

Quasi mai si desidera eseguire il rollback di una transazione con un'eccezione, a meno che non si sia realmente in uno stato eccezionale. L'antipattern tipico dell'utilizzo di un'eccezione non controllata per il rollback di una transazione si avvantaggia di un effetto collaterale ed è inefficiente a causa del costo dell'eccezione e ancor di più quando si utilizza Groovy. Ma 'withTransaction' è _non_ l'unico modo corretto per farlo. Basta usare 'TransactionAspectSupport.currentTransactionStatus(). SetRollbackOnly() ' –

3

Session e TransactionStatus sono due cose completamente diverse. La Sessione è un'astrazione che ti dà accesso a tutte le funzionalità di ibernazione mentre il TransactionStatus può essere usato per controllare la transazione corrente.

withSession può essere utilizzato se è necessario l'accesso diretto alle funzioni di ibernazione. Questo può essere utile se si desidera utilizzare una funzione di ibernazione che non è supportata direttamente da Grails/GORM.