2012-06-15 16 views
39

Tôi nên thích điều gì hơn khi cập nhật cơ sở dữ liệu? Các ưu điểm & chống lại với một trong hai phương pháp là gì và khi nào tôi sẽ sử dụng cái này hay cái kia?Entitymanager.flush() VS EntityManager.getTransaction(). Cam kết - Tôi nên thích điều gì?

public void disemployEmployee(Integer employeeId, Date endDate) { 
    Employee employee = (Employee)em.find("Employee", employeeId); 
    employee.getPeriod().setEndDate(endDate); 
    em.flush(); 
} 

public void disemployEmployee(Integer employeeId, Date endDate) { 
    Employee employee = (Employee)em.find("Employee", employeeId); 
    em.getTransaction().begin(); 
    employee.getPeriod().setEndDate(endDate); 
    em.getTransaction().commit(); 
} 

Trả lời

42

Trong ví dụ đầu tiên của bạn, thay đổi đối với dữ liệu được phản ánh trong cơ sở dữ liệu sau khi gặp phải tuôn ra, nhưng nó vẫn là trong giao dịch.

Nhưng trong ví dụ thứ hai, bạn thực hiện giao dịch ngay lập tức. Do đó các thay đổi được thực hiện vào cơ sở dữ liệu giao dịch & cũng kết thúc ở đó.

Đôi khi, việc tuôn ra có thể hữu ích để duy trì dữ liệu giữa giao dịch đang diễn ra & rồi cuối cùng cũng cam kết các thay đổi sau đó. Vì vậy, bạn cũng có thể khôi phục các thay đổi trước đó nếu xảy ra một số vấn đề sau đó, như cho việc chèn/cập nhật hàng loạt.

+8

Trong ví dụ đầu tiên không có giao dịch, do đó, có một ngoại lệ ném tại tuôn ra(). – DataNucleus

+1

@DataNucleus Tôi nghĩ trong CMT, chúng tôi không phải bắt đầu/kết thúc giao dịch theo cách thủ công. –

+2

chắc chắn nhưng anh ấy ở CMT? trong ví dụ khác của ông, ông bắt đầu txn, do đó, đó là giả định duy nhất tôi có thể làm cho – DataNucleus

14

Bạn đã đọc javadoc cho tuôn ra và cam kết và biết tuôn ra đó là chỉ để sử dụng trong vòng một giao dịch? Nó tuôn ra (nhưng không cam kết), trong khi cam kết cam kết dữ liệu (rõ ràng). Chúng khác biệt; không có "sở thích". Ví dụ đầu tiên là sai, và nên dẫn đến một ngoại lệ khi gọi flush (TransactionRequiredException)

+1

tôi có thể làm gì với flush() mà tôi không thể làm mà không sử dụng flush()? – Rox

+1

Flush đặt dữ liệu vào kho dữ liệu, và không có dữ liệu không có, do đó truy vấn có thể trả về dữ liệu cũ. Có thể đọc thông số JPA trên flush() – DataNucleus

+2

Vâng, mọi thứ API nói về flush() là "Đồng bộ hóa bối cảnh persistence cho cơ sở dữ liệu bên dưới" và tôi chưa bao giờ sử dụng nó trước đây, nhưng giao dịch của tôi vẫn đặt dữ liệu vào cơ sở dữ liệu khi gọi ' EntityManager.getTransaction.commit() '. Và tôi đã không gọi EntityManager.flush()! Vì vậy, tôi không thể hiểu việc sử dụng flush() khi bạn có thể làm tất cả mọi thứ nó thậm chí không có nó. – Rox

3

Cả hai mẫu mã của bạn không tồn tại hoặc hợp nhất trạng thái thực thể được ghi vào DB.

Tôi không nghĩ rằng nó phù hợp để so sánh EntityManager.flush()EnityManager.EntityTransaction.commit().

flush() PHẢI được đính kèm trong ngữ cảnh giao dịch và bạn không phải thực hiện rõ ràng trừ khi cần (trong trường hợp hiếm hoi), khi EntityTransaction.commit() thực hiện điều đó cho bạn.

Tham khảo link này Is it necessary to call a flush() (JPA interface) in this situation?

Tham khảo link này Question about flushing with JPA before a query is called cho một kịch bản để sử dụng flush()

+0

Như tôi đã hỏi DataNucleus: Tôi có thể làm gì với flush() mà tôi không thể thực hiện mà không sử dụng nó? – Rox

+0

Đã cập nhật câu trả lời của tôi. Hy vọng liên kết sẽ trả lời câu hỏi của bạn. –

+0

@AhamedMustafaM 'Cả hai mẫu mã của bạn không tồn tại hoặc hợp nhất trạng thái thực thể được ghi vào DB' Không, nếu thực thể được quản lý, các thay đổi sẽ được đồng bộ hóa trong cơ sở dữ liệu ngầm. –

0

Tôi sẽ chuyển đến giao dịch được quản lý container bất cứ khi nào có thể. Các giao dịch được quản lý Bean thường yêu cầu nhiều mã hơn, vì các khả năng ngoại lệ. Ngoài ra, nó dễ bị lỗi hơn (rollback, quản lý tài nguyên).

Điều đó nói rằng, tôi sẽ sử dụng lệnh xả sau khi cam kết trong chế độ quản lý vùng chứa. Bằng cách đó tôi có thể bắt PersistenceExceptions có thể có trong mô-đun lưu trữ của mình và chuyển đổi nó sang một số Ngoại lệ có ý nghĩa hơn cho mô-đun trường hợp sử dụng của tôi. Điều này bởi vì tôi không muốn xử lý các ngoại lệ dành riêng cho lưu trữ tại đây, bởi vì tôi có thể hoán đổi mô-đun lưu trữ cho một thứ không sử dụng JPA ... mà không bao giờ xảy ra với tôi :)

0

Tôi nghĩ phần còn thiếu là , flush() chỉ cần thêm vào các nguồn dữ liệu để sẵn sàng cam kết, cung cấp các id thực nhưng không tồn tại theo mặc định.

Vì vậy, nếu bạn cần flush() để làm việc như cam kết(), bạn cần phải thiết lập các chế độ tuôn ra để Commit trong EntityManager bởi:

void setFlushMode(FlushModeType flushMode) 
Set the flush mode that applies to all objects contained in the persistence context. 

Lưu ý rằng FlushModeType là một enum có hai giá trị:

FlushModeType AUTO (Mặc định) Xảy ra để xảy ra khi thực thi truy vấn. Vì: JPA 1.0 FlushModeType COMMIT Flushing xuất hiện tại giao dịch cam kết. Nhà cung cấp có thể tuôn ra vào những lúc khác, nhưng không bắt buộc. Từ: JPA 1,0

Tôi hy vọng điều này giúp đỡ

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