2010-06-24 18 views
8

Tôi đã đọc về kế hoạch chi tiết mặt trời GenericDAO thực hiện và Gavin King thực hiện việc này để sử dụng với Hibernate. Có vẻ như anh ấy không đề cập đến bất kỳ điều gì về xử lý giao dịch:Thiết kế kém cho DAO có quản lý giao dịch không?

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

Tôi đang bối rối về nơi tôi nên đặt bắt đầu/kết thúc giao dịch. Hiện nay họ đang ở trong DAO rằng mở rộng này GenericHibernateDAO

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

việc xử lý giao dịch nên được quản lý bởi người gọi của DAO trong tầng ứng dụng?

Trả lời

16

Nói chung cách tốt nhất là quản lý giao dịch trong lớp dịch vụ không có trong lớp DAO. Mỗi phương pháp DAO thường xử lý một hoạt động cụ thể và một phương thức dịch vụ tổng hợp chúng trong một giao dịch.

+0

Đó là +1 - bạn đánh bại tôi đến số –

3

Giao dịch phải được quản lý trong tầng ứng dụng. Nói ví dụ, bạn có một AccountDAO:

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

    } 

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

Nếu tôi muốn chuyển tiền giữa các tài khoản, tôi sẽ gọi DebitAccount trên một tài khoản và CreditAccount ngày khác. Tôi muốn các cuộc gọi này xảy ra trong cùng một giao dịch. DAO không thể biết điều đó, nhưng tầng ứng dụng sẽ như thế.

Nếu giao dịch được quản lý ở cấp DAO, bạn cần tạo phương thức TransferMoney khác trên DAO để thực hiện trong một giao dịch. Điều này cuối cùng sẽ sưng lên tầng DAO của bạn và, cho các hoạt động phức tạp, mang lại logic kinh doanh mà có lẽ không nên ở đó. Và nó thậm chí còn lộn xộn hơn nếu bạn có một thao tác đòi hỏi nhiều DAO phải tham gia vào một giao dịch duy nhất.

+0

để lấy ví dụ như hệ thống cho vay, nơi có nhiều truy vấn để quyết định báo giá, sau đó báo giá được viết cho DB, bạn có bắt đầu giao dịch không trước tất cả các lần đọc? Ngoài ra, 'GenericDao' không có phương thức công khai để truy xuất Session để bắt đầu giao dịch? – James

+1

@James - Tôi sẽ bắt đầu giao dịch trước khi bất kỳ lần ghi nào xảy ra, nhưng không nhất thiết trước khi đọc. Và có, sẽ không cần DAO phải lo lắng về giao dịch, vì vậy không cần phương pháp nào. Các giao dịch sẽ được quản lý trong lớp dịch vụ. –

+0

Ok cảm ơn vì điều đó. Một điều cuối cùng nếu bạn không nhớ - lớp dịch vụ bắt đầu giao dịch nhưng để nó thực hiện điều này, nó cần truy cập vào một 'Session' để gọi 'session.beginTransaction()'. Nếu nó không phải là DAO cung cấp lớp dịch vụ với 'Session', nó xuất phát từ đâu? tĩnh 'SessionFactory'? – James

Các vấn đề liên quan