Tôi đã đọc trên các mức cách ly giao dịch khác nhau và xuất hiện trên mức cách ly SERIALIZABLE
. Tôi cũng biết rằng các cơ sở dữ liệu như Postgres, Oracle và MySQL hỗ trợ cú pháp SELECT .. FOR UPDATE
.Giao dịch có thể thực hiện được so với CHỌN ĐỂ CẬP NHẬT
Tuy nhiên, tôi đã nhầm lẫn về cách sử dụng chúng khi tôi muốn khóa một hàng (hoặc một loạt hàng) mà tôi muốn thực hiện cập nhật.
Khi sử dụng JPA trong quá khứ, tôi luôn sử dụng @Transactional
kết hợp với một LockModeType.PESSIMISTIC_WRITE
trên truy vấn. Điều này chuyển sang sử dụng mức cách ly READ_COMMITTED
với một số SELECT .. FOR UPDATE
trong SQL.
Nhưng bây giờ, sau khi đọc về SERIALIZABLE
, tôi đang tự hỏi điều gì sẽ khác nếu tôi sử dụng @Transactional(isolation=SERIALIZABLE)
với một bình thường SELECT
(ví dụ em.findById để lấy một thực thể tách rời), tiếp theo là một UPDATE
(hợp nhất của thực thể).
Hành vi có giống nhau không?
Ví dụ: tôi có hệ thống Ngân hàng và tôi muốn chuyển tiền giữa hai tài khoản. Tôi yêu cầu các tài khoản này không được can thiệp vào, trong khi quá trình chuyển đang diễn ra. Vì vậy, giả sử tôi ghi nợ một tài khoản với -100 và ghi có vào tài khoản khác. Điều gì sẽ là cách tốt nhất để đảm bảo rằng các tài khoản này chỉ có sẵn cho giao dịch thực hiện cập nhật?
Giả sử rằng tôi đang điều khiển các thực thể tách rời JPA, vì vậy trước khi cập nhật, tôi sẽ phải đọc chúng từ DB, ví dụ: findById().
- Sử dụng
@Transactional(isolation=READ_COMMITTED)
, em.findById vớiLockModeType.PESSIMISTIC_WRITE
(ví dụ:SELECT .. FOR UPDATE
), và sau đó em.merge (ví dụ:UPDATE
)? - HOẶC Sử dụng
@Transactional(isolation=SERIALIZABLE)
, em.findById, và sau đó em.merge (ví dụ:UPDATE
)?
"* với tất cả mọi thứ SERIALIZABLE luôn bị khóa *" không đúng như một tuyên bố chung. Điều này phụ thuộc rất nhiều vào việc thực hiện DBMS (Postgres ví dụ không làm điều đó) –
Đó là sự thật "PostgreSQL ví dụ không làm điều đó" trong PostgreSQL tuần tự sẽ làm tất cả các câu lệnh chọn không có Khóa nhưng khi xảy ra đồng thời không thể cấp toàn vẹn tuần tự – deFreitas