2010-02-25 36 views
9

A có thực thể JPA có trường dấu thời gian và được phân biệt bằng trường nhận dạng phức. Những gì tôi cần là cập nhật dấu thời gian trong một thực thể đã được lưu trữ, nếu không hãy tạo và lưu trữ thực thể mới bằng dấu thời gian hiện tại.Tạo mới hoặc cập nhật thực thể hiện tại cùng một lúc với JPA

Vì hóa ra nhiệm vụ không đơn giản như khi nhìn từ cảnh đầu tiên. Vấn đề là trong môi trường đồng thời tôi nhận được khó chịu "Độc đáo chỉ số hoặc vi phạm chính tiểu học" ngoại lệ. Đây là mã của tôi:

// Load existing entity, if any. 
Entity e = entityManager.find(Entity.class, id); 
if (e == null) { 
    // Could not find entity with the specified id in the database, so create new one. 
    e = entityManager.merge(new Entity(id)); 
} 
// Set current time... 
e.setTimestamp(new Date()); 
// ...and finally save entity. 
entityManager.flush(); 

Xin lưu ý rằng trong ví dụ này, mã định danh thực thể không được tạo khi chèn, nó được biết trước.

Khi hai hoặc nhiều luồng chạy khối mã này song song, chúng có thể đồng thời nhận được null từ cuộc gọi phương thức entityManager.find(Entity.class, id), do đó chúng sẽ cố gắng lưu hai hoặc nhiều thực thể cùng một lúc. .

Tôi nghĩ rằng có rất ít giải pháp cho vấn đề.

  1. Chắc chắn tôi có thể đồng bộ hóa khối mã này với khóa toàn cầu để ngăn truy cập đồng thời vào cơ sở dữ liệu, nhưng đó có phải là cách hiệu quả nhất không?
  2. Một số cơ sở dữ liệu hỗ trợ tuyên bố MERGE rất tiện dụng cập nhật hiện tại hoặc tạo hàng mới nếu không tồn tại. Nhưng tôi nghi ngờ rằng OpenJPA (JPA thực hiện sự lựa chọn của tôi) hỗ trợ nó.
  3. Sự kiện nếu JPA không hỗ trợ SQL MERGE, tôi luôn có thể quay trở lại JDBC cũ và làm bất cứ điều gì tôi muốn với cơ sở dữ liệu. Nhưng tôi không muốn rời khỏi API thoải mái và lộn xộn với sự kết hợp JDBC + SQL lông.
  4. Có một mẹo kỳ diệu để khắc phục sự cố bằng cách sử dụng API JPA chuẩn, nhưng tôi chưa biết.

Vui lòng trợ giúp.

Trả lời

1

Bạn đang đề cập đến sự cô lập giao dịch của các giao dịch JPA. I E. hành vi của các giao dịch khi họ truy cập tài nguyên của các giao dịch khác là gì.

Theo this article:

READ_COMMITTED là mức cô lập giao dịch mặc định sẽ sử dụng [..] EJB3 JPA

Điều này có nghĩa rằng - có, bạn sẽ có vấn đề với các mã trên .

Nhưng JPA không hỗ trợ các mức cách ly tùy chỉnh.

This thread thảo luận chủ đề rộng rãi hơn. Tùy thuộc vào việc bạn sử dụng Spring hay EJB, tôi nghĩ bạn có thể sử dụng chiến lược giao dịch thích hợp.

+0

Cả hai liên kết đều bị hỏng – Sergey

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