2010-06-24 12 views
8

Ho letto sull'implementazione del modello di sole GenericDAO e su quello di Gavin King per l'uso con Hibernate. Sembra che non menziona nulla sulla gestione delle transazioni:È una progettazione scadente per i DAO gestire le transazioni?

public abstract class GenericHibernateDAO<T, ID extends Serializable> { 
    protected Session getSession() { 
     return HibernateUtil.getSessionFactory().getCurrentSession(); 
    } 

    public T makePersistent(T entity) { 
     getSession().saveOrUpdate(entity); 
     return entity; 
    } 
} 

Sono perplesso su dove devo mettere l'inizio/fine della transazione. Attualmente sono all'interno dei DAO che estendere questo GenericHibernateDAO

public class FooHibernateDAO extends GenericHibernateDAO<Foo, Long> { 
    public Foo saveFoo(Foo foo) { 
     getSession().beginTransaction(); 
     makePersistent(foo); 
     getSession().getTransaction().commit(); 
    } 
} 

caso in cui la gestione delle transazioni essere gestito dal chiamante del DAO nel livello di applicazione?

risposta

16

In genere, la procedura migliore consiste nel gestire le transazioni nel livello di servizio non nel livello DAO. Ogni metodo DAO generalmente gestisce un'operazione specifica e un metodo di servizio li aggrega in un'unica transazione.

+0

Questo è tutto +1 - mi hai battuto su di esso –

3

Le transazioni devono essere gestite nel livello applicazione. Diciamo per esempio si ha avuto un AccountDAO:

public class AccountDAO { 
    public void DebitAccount(int accountId, int dollars) { 

    } 

    public void CreditAccount(int accountId, int dollars) { 
    } 
} 

Se avessi voluto trasferire denaro tra i conti, io chiamerei DebitAccount su un conto e CreditAccount su un altro. Vorrei che queste chiamate accadessero nella stessa transazione. Il DAO non può saperlo, ma lo farebbe il livello dell'applicazione.

Se le transazioni sono state gestite sul livello DAO, è necessario creare un altro metodo TransferMoney sul DAO per eseguirlo in un'unica transazione. Questo alla fine gonfierà il tuo livello DAO e, per operazioni complesse, porterà in una logica di business che probabilmente non dovrebbe esserci. E diventa ancora più complicato se si dispone di un'operazione che richiede più DAO per essere coinvolti in una singola transazione.

+0

quindi prendi un esempio come un sistema di prestito in cui sono fatte molte query per decidere su un preventivo, quindi la citazione è scritta nel DB, inizieresti la transazione prima di tutte le letture? Anche il 'GenericDaoDao 'non ha un metodo pubblico per recuperare la sessione per avviare la transazione? – James

+1

@James - Vorrei iniziare la transazione prima che si verifichino eventuali scritture, ma non necessariamente prima delle letture. E sì, non ci sarebbe bisogno che i DAO si preoccupassero delle transazioni, quindi non è necessario alcun metodo. Le transazioni sarebbero gestite nel livello di servizio. –

+0

Ok grazie per quello. Un'ultima cosa, se non ti dispiace, il livello di servizio avvia la transazione, ma per fare ciò ha bisogno di accedere a una "Session" per chiamare 'session.beginTransaction()'. Se non è il DAO che fornisce il livello di servizio con 'Session', da dove viene? il 'SessionFactory' statico? – James

Problemi correlati