Tôi đang sử dụng EclipseLink 2.3.0. Tôi có một phương pháp mà tôi đang gọi từ một thử nghiệm đơn vị (vì thế bên ngoài của một container, không JTA) trông như thế này:JPA/EclipseLink: EntityManager.getTransaction() có tạo giao dịch mới hoặc trả lại giao dịch đang hoạt động không?
EntityManager em = /* get an entity manager */;
em.getTransaction().begin();
// make some changes
em.getTransaction().commit();
Những thay đổi đã không được tồn cơ sở dữ liệu, và nhìn này cho một thời gian dài và cuối cùng nhận ra rằng EntityManager.getTransaction() thực sự trả về một EntityTransaction MỚI, chứ không phải là cùng một trong cả hai cuộc gọi. Hiệu ứng là cuộc gọi đầu tiên tạo một giao dịch mới và bắt đầu cuộc gọi đó và cuộc gọi thứ hai tạo ra giao dịch KHÁC và cam kết nó. Bởi vì giao dịch đầu tiên không bao giờ được cam kết, các thay đổi sẽ không được lưu. Chúng tôi xác nhận này như thế này:
log.info(em.getTransaction().toString());
log.info(em.getTransaction().toString());
nào dẫn đến các thông điệp ghi:
INFO: org.ecl[email protected]1e34f445
INFO: org.ecl[email protected]706a4d1a
Hai xác minh rằng có hai trường hợp khác nhau khác nhau đối tượng ID của. Thay đổi mã này:
EntityManager em = /* get an entity manager */;
EntityTransaction tx = em.getTransaction();
tx.begin();
// make some changes
tx.commit();
... khắc phục được sự cố. Bây giờ khi tôi chạy mã, tôi thấy các câu lệnh SQL được tạo ra để thực hiện công việc cơ sở dữ liệu và tìm trong cơ sở dữ liệu, dữ liệu đã được thay đổi.
Tôi hơi ngạc nhiên bởi kết quả này, vì tôi đã thấy nhiều ví dụ mã trực tuyến (đối với JPA nói chung và EclipseLink cụ thể) đề xuất mã chúng tôi sử dụng để quản lý giao dịch. Tôi đã tìm kiếm rất nhiều thông tin về điều này nhưng không tìm thấy gì cả. Vì vậy những gì đang xảy ra?
Tôi đã xem thông số JPA để biết điều gì đó chỉ định chính xác những gì getTransaction() thực hiện và không cụ thể nếu giao dịch mới hoặc giống nhau. Có một thiết lập trong persistence.xml điều khiển này? Có phải hành vi cụ thể đối với từng triển khai của thông số JPA không?
Cảm ơn bạn rất nhiều vì đã có bất kỳ thông tin hoặc hướng dẫn nào.
Có lẽ tôi phải rõ ràng hơn - mã tôi đăng KHÔNG hoạt động. Tôi đã chỉnh sửa câu hỏi để làm rõ. –
Tôi hiểu điều đó. Quan điểm của tôi là nó * nên * làm việc, vì đặc tả JPA chứa các mẫu mã whet 'em.getTransaction()' được sử dụng để bắt đầu và cam kết giao dịch. Vì vậy, nó phải là một lỗi trong EclipseLink, trừ khi, như tôi đã nói, mã giữa bắt đầu và cam kết đã cam kết hoặc hoàn nguyên giao dịch. Câu trả lời của tôi không phải là giải pháp cho vấn đề của bạn, nhưng xác nhận rằng mã sẽ hoạt động. Tôi đề nghị nộp một lỗi cho EclipseLink. –