Đối với Dữ liệu mùa xuân 1.6 trở lên
@Lock
được hỗ trợ trên các phương thức CRUD kể từ phiên bản 1.6 của Spring Data JPA (trên thực tế, đã có mốc quan trọng
có sẵn). Xem vé
này để biết thêm chi tiết.
Với phiên bản đó, bạn chỉ cần khai báo như sau:
interface WidgetRepository extends Repository<Widget, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
Widget findOne(Long id);
}
Điều này sẽ khiến phần triển khai CRUD của proxy kho lưu trữ sao lưu áp dụng LockModeType đã định cấu hình cho find(…)
gọi trên EntityManager
.
Mặt khác,
Đối với phiên bản trước của Spring Data 1.6
Dữ liệu mùa xuân bi quan @Lock
chú thích chỉ áp dụng (như bạn đã chỉ ra) cho các truy vấn. Không có chú thích nào mà tôi biết có thể ảnh hưởng đến toàn bộ giao dịch. Bạn có thể tạo findByOnePessimistic
phương thức gọi findByOne
bằng khóa bi quan hoặc bạn có thể thay đổi findByOne
để luôn có được một khóa bi quan.
Nếu bạn muốn thực hiện giải pháp của riêng mình, bạn có thể có thể. Dưới mui xe, @Lock
chú thích được xử lý bởi LockModePopulatingMethodIntercceptor
làm như sau:
TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);
Bạn có thể tạo một số trình quản lý khóa tĩnh có ThreadLocal<LockMode>
biến thành viên và sau đó có một khía cạnh được bao bọc xung quanh mọi phương thức trong mọi kho lưu trữ được gọi là bindResource với chế độ khóa được đặt trong ThreadLocal. Điều này sẽ cho phép bạn đặt chế độ khóa trên cơ sở mỗi luồng. Sau đó, bạn có thể tạo @MethodLockMode
của riêng mình chú thích sẽ bao bọc phương thức trong một khía cạnh đặt chế độ khóa dành riêng cho luồng trước khi chạy phương thức và xóa nó sau khi chạy phương thức.
Liên kết tài nguyên:
- Làm cách nào để bật LockModeType.PESSIMISTIC_WRITE khi tìm kiếm các thực thể bằng Spring Data JPA?
- Cách thêm tùy chỉnh phương thức sang Spring Data JPA
- Thời gian chờ Khóa bi quan của Spring Data với Postgres
- API truy vấn JPA
Nhiều ví dụ về thời gian chờ khóa bi quan
Đặt khóa bi quan
Một đối tượng thực thể có thể được khóa rõ ràng bằng phương thức khóa:
em.lock(employee, LockModeType.PESSIMISTIC_WRITE);
Đối số đầu tiên là một đối tượng thực thể. Đối số thứ hai là chế độ khóa được yêu cầu.
Một TransactionRequiredException
được ném nếu không có giao dịch đang hoạt động khi khóa được gọi vì khóa rõ ràng yêu cầu một giao dịch đang hoạt động.
Một LockTimeoutException
được ném nếu không thể cấp khóa bi quan được yêu cầu:
- Một
PESSIMISTIC_READ
yêu cầu khóa không thành công nếu người dùng khác (được đại diện bởi một phiên bản EntityManager khác) hiện đang giữPESSIMISTIC_WRITE
khóa đối tượng cơ sở dữ liệu đó. -
PESSIMISTIC_WRITE
yêu cầu khóa không thành công nếu người dùng khác hiện đang sở hữuPESSIMISTIC_WRITE
khóa hoặc mộtPESSIMISTIC_READ
khóa đối tượng cơ sở dữ liệu đó.
Đặt gợi ý truy vấn (Phạm vi)
Gợi ý truy vấn có thể được đặt trong các phạm vi sau (từ toàn cầu đến cục bộ):
Đối với toàn bộ đơn vị duy trì - sử dụng persistence.xml
tài sản:
<properties>
<property name="javax.persistence.query.timeout" value="3000"/>
</properties>
Đối với EntityManagerFactory - sử dụng createEntityManagerFacotory
phương pháp:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 4000);
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("pu", properties);
Đối với EntityManager - sử dụng createEntityManager
phương pháp:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 5000);
EntityManager em = emf.createEntityManager(properties);
hoặc sử dụng phương thức setProperty:
em.setProperty("javax.persistence.query.timeout", 6000);
Đối với named query
định nghĩa - sử dụng hints
phần tử:
@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})
Để thực thi truy vấn cụ thể - sử dụng setHint
phương thức (trước khi thực thi truy vấn):
query.setHint("javax.persistence.query.timeout", 8000);