2014-10-30 21 views
7

Utilizzo la gestione delle transazioni basata su annotazione con Spring JDBC.Operazione JDBC Rollback Spring quando non è in transazione

Mi piacerebbe avere Spring throw un'eccezione quando per errore ho dimenticato di annotare con @Transactional un metodo di servizio che inserisce/aggiorna/cancella.

Per impostazione predefinita i dati possono essere inseriti/aggiornati/cancellati anche non all'interno di una transazione.

+1

È possibile utilizzare Propagation.MANDATORY nel livello DAO –

+0

È stato scelto di utilizzare @Transactional solo sul livello di servizio poiché le transazioni partono sempre da lì. – yannisf

+0

Bene, è possibile scorrere tutte le classi di servizio tramite riflessione e verificare se tutte contengono annotazioni @Transactional –

risposta

1

È possibile utilizzare Propagation.MANDATORY nel proprio livello DAO.

Propagation.MANDATORY non avvierà una transazione. Verificherà se il metodo perticolare è collegato a una transazione o meno, se il contenitore non genera un'eccezione.

0

Secondo la documentazione (docs molla) è solo metadati per dare un'indicazione che il metodo o l'interfaccia può essere configurato da qualcosa che è 'transazionale a conoscenza' (cioè

Con solo tx: annotazioni-driven e non attributi @Transactional credo che si ottiene il transactionality "default" applicata:.

impostazione di propagazione è rICHIESTO livello di isolamento è pREDEFINITO transazione è di lettura/scrittura default timeout delle transazioni per il timeout predefinito della transazione sottostante.. sistema, o nessuno se i timeout non sono supportati. ny RuntimeException attiva il rollback e qualsiasi eccezione verificata non lo fa. Supponendo che si sta utilizzando il tx: annotazioni di guidarla attraverso un gestore delle transazioni poi perdendo l'attributo @Transactional significa che non è possibile applicare tali proprietà in sola lettura, l'isolamento, la propagazione, rollbackFor, noRollbackFor ecc

Credo che MVC sia leggermente diverso: la sessione di ibernazione è legata direttamente alla richiesta MVC, ovvero quando viene ricevuta la richiesta, la transazione inizia.

Torna al tuo esempio, il codice per getSession() in HibernateDAOSupport è la seguente:

protected final Session getSession() 
    throws DataAccessResourceFailureException, IllegalStateException 
{ 
    return getSession(this.hibernateTemplate.isAllowCreate()); 
} 

Che a sua volta chiama a:

/** * ottenere una sessione Hibernate, sia da la transazione corrente o * una nuova. Quest'ultimo è consentito solo se "allowCreate" è vero. * .......

protected final Session getSession() 
    throws DataAccessResourceFailureException, IllegalStateException { 
return getSession(this.hibernateTemplate.isAllowCreate()); 
} 

che chiama in definitiva a:

/** * .... * @param allowCreate se una sessione non transazionale deve essere creato * quando nessuna sessione transazionale può essere trovato per il thread corrente * .... */

private static Session doGetSession(
    SessionFactory sessionFactory, Interceptor entityInterceptor, 
SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate) 

Fondamentalmente, un Transazione: sessione è legato 1: 1 AFA ik, e l'unico modo per eseguire senza una transazione è usare dire JBoss che ha un livello di persistenza 'cotto in' che fornisce la transazione per te (sotto le copertine). Anche se chiami getQuery() dopo getSession() hai ancora effettivamente una transazione che si verifica in quanto è una connessione JDBC/Hibernate.

Problemi correlati