2010-06-24 8 views
8

He estado leyendo acerca de la implementación de sol modelo GenericDAO y toma de Gavin King en esto para el uso con Hibernate. Parece que no menciona nada acerca de la manipulación de transacciones:¿Es un diseño deficiente para los DAO gestionar las transacciones?

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; 
    } 
} 

estoy desconcertado en cuanto a donde debo poner el inicio/final de la transacción. Actualmente se encuentran dentro de los DAOs que extender esta GenericHibernateDAO

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

En caso de que el manejo de transacciones será administrado por la persona que llama de la DAO en el nivel de aplicación?

Respuesta

16

Generalmente la mejor práctica es la gestión de transacciones en la capa de servicio no en la capa DAO. Cada método DAO generalmente maneja una operación específica y un método de servicio los agrega en una transacción.

+0

Eso es todo +1 - me lo ganaste –

3

Las transacciones deben ser gestionados en el nivel de aplicación. Digamos por ejemplo que tenía un AccountDAO:

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

    } 

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

Si quería transferir dinero entre cuentas, que yo llamaría DebitAccount en una cuenta y CreditAccount en otro. Me gustaría que estas llamadas ocurrieran en la misma transacción. El DAO no puede saberlo, pero el nivel de aplicación lo haría.

Si las transacciones se administraron en el nivel DAO, necesitaría crear otro método TransferMoney en el DAO para hacerlo en una transacción. Esto eventualmente hincharía su nivel DAO y, para operaciones complejas, traería lógica comercial que probablemente no debería estar allí. Y se vuelve aún más complicado si tiene una operación que requiere varios DAO para participar en una sola transacción.

+0

Así que toma un ejemplo como un sistema de préstamo donde se realizan muchas consultas para decidir sobre un presupuesto, luego se escribe la cotización en la base de datos, ¿comenzarías la transacción? antes de todas las lecturas? Además, ¿el 'GenericDao' no tiene un método público para recuperar la sesión para iniciar la transacción? – James

+1

@James: comenzaría la transacción antes de que se produzca cualquier escritura, pero no necesariamente antes de las lecturas. Y sí, no habría necesidad de que los DAO se preocupen por las transacciones, por lo que no se necesita ningún método. Las transacciones se administrarían en la capa de servicio. –

+0

Ok gracias por eso. Una última cosa, si no le importa - la capa de servicio se inicia la transacción, pero a fin de que al hacer esto se necesita tener acceso a una 'sesión' con el fin de llamar 'session.beginTransaction()'. Si no es el DAO el que proporciona la capa de servicio con la 'Sesión', ¿de dónde viene? el 'SessionFactory' estático? – James

Cuestiones relacionadas