2012-03-28 26 views

Trả lời

24

Câu trả lời ngắn gọn: Không, bạn sẽ không có thực thể trong cơ sở dữ liệu.

Câu trả lời dài hơn: hibernate đủ thông minh để không gửi chèn/cập nhật cho DB cho đến khi nó biết giao dịch sẽ được cam kết hoặc quay lại (mặc dù hành vi này có thể được thay đổi bằng cách đặt FlushMode khác) trường hợp bằng cách gọi lệnh flush bạn buộc SQL phải được gửi đến DB nhưng bạn vẫn có giao dịch DB để bảo vệ bạn, khi bạn gọi rollback, giao dịch DB sẽ được khôi phục lại các thay đổi được thực hiện bên trong chính nó và do đó không có gì thực sự được lưu . Lưu ý rằng tùy thuộc vào mức cô lập giao dịch được định cấu hình của bạn, có lẽ các giao dịch khác sẽ có thể thấy theo một cách nào đó mà EntityA bạn đã lưu trong khoảng thời gian ngắn giữa lưu và khôi phục. Cũng lưu ý rằng tuôn ra được gọi tự động khi bạn cố gắng đọc từ DB, trong 99% các trường hợp gọi nó rõ ràng là không cần thiết. Một ngoại lệ mà bạn nghĩ đến là khi thử nghiệm đơn vị với các kiểm tra tự động quay lại.

+0

tôi không thể nghĩ về giao dịch ngủ đông giống như giao dịch DB thực sự bằng cách nào đó. cảm ơn bạn ! bạn có thể kiểm tra câu hỏi này không? cho phép tôi hỏi câu hỏi này mà bạn đã trả lời. http://stackoverflow.com/questions/9903872/hibernate-session-save-creating-not-neccessary-insert-statements – kommradHomer

+1

Phần này của câu trả lời là không chính xác: "hibernate đủ thông minh không gửi chèn/cập nhật cho DB cho đến khi nó biết nếu giao dịch sẽ được cam kết hoặc quay trở lại ".Hibernate S send gửi chèn/cập nhật cho DB bất cứ lúc nào phiên được xóa bỏ, và điều này có thể được trước khi nó biết nếu giao dịch được cam kết hoặc quay trở lại. – SteveT

+0

@SteveT bạn có biết bất kỳ kịch bản nào trong đó phiên sẽ bị xóa mà không cần gọi .flush() hoặc cam kết giao dịch không? – ilcavero

19

Khi bạn gọi session.save(a) Hibernate về cơ bản nhớ một nơi nào đó trong phiên mà đối tượng này phải được lưu. Nó có thể quyết định nếu anh ta muốn phát hành INSERT INTO... ngay lập tức, một thời gian sau đó hoặc trên cam kết. Đây là một cải tiến hiệu suất, cho phép Hibernate chèn hàng loạt hoặc tránh chúng nếu giao dịch được khôi phục.

Khi bạn gọi session.flush(), Hibernate buộc phải phát hành INSERT INTO... đối với cơ sở dữ liệu. Thực thể được lưu trữ trong cơ sở dữ liệu, nhưng chưa được cam kết. Tùy thuộc vào mức cô lập giao dịch, nó sẽ không được nhìn thấy bởi các giao dịch đang chạy khác. Nhưng bây giờ cơ sở dữ liệu biết về hồ sơ.

Khi bạn gọi transaction.rollback(), Hibernate sẽ cuộn lại giao dịch cơ sở dữ liệu. Cơ sở dữ liệu xử lý rollback, do đó loại bỏ đối tượng mới được tạo ra.

Bây giờ, hãy xem xét trường hợp không có flush(). Trước hết, bạn không bao giờ chạm vào cơ sở dữ liệu để hiệu suất là tốt hơn và rollback về cơ bản là một no-op. Mặt khác, nếu mức cô lập giao dịch là READ UNCOMMITTED, các giao dịch khác có thể xem bản ghi được chèn ngay cả trước khi cam kết/khôi phục. Nếu không có flush() điều này sẽ không xảy ra, trừ khi Hibernate không quyết định flush() ngầm.

+0

bạn có thể kiểm tra câu hỏi khác của tôi đã khiến tôi đặt câu hỏi này không? http://stackoverflow.com/questions/9903872/hibernate-session-save-creating-not-neccessary-insert-statements – kommradHomer

7

Tôi nghĩ bạn bị nhầm lẫn với flushcommit.

flush() đồng bộ hóa trạng thái với cơ sở dữ liệu nhưng không thực hiện cam kết. Nhà nước vẫn có thể nhìn thấy bằng giao dịch, do đó bạn có thể gọi rollback để rollback.

Vì vậy, câu trả lời cho câu hỏi của bạn là: không, bạn không có thực thể (a) trong cơ sở dữ liệu.

+0

cảm ơn bạn đời. sự nhầm lẫn chính của tôi là thiếu kiến ​​thức về giao dịch DB thực trên trang web DB. – kommradHomer

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