Hibernate JPA乐观锁定:如果记录已更新,如何防止删除,反之亦然?
我需要我的应用程序具有以下行为:Hibernate JPA乐观锁定:如果记录已更新,如何防止删除,反之亦然?,hibernate,jpa,spring-data-jpa,optimistic-locking,Hibernate,Jpa,Spring Data Jpa,Optimistic Locking,我需要我的应用程序具有以下行为: @Entity public class Order { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; @Version private Integer version; // many other fields 情景1 用户A查看订单 用户B查看相同的订单 用户A删除订单 用户B请求更新订单。这应该失败 情景2
@Entity
public class Order {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Version
private Integer version;
// many other fields
情景1
@Version
实现这种乐观锁定行为:
@Entity
public class Order {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Version
private Integer version;
// many other fields
删除时,UI客户端会向服务器提供订单id列表以及每个订单id的版本号。此[post()提到了一个标准解决方案:
if (entity.getVersion() != dto.getVersion()) {
throw new OptimisticLockException("...");
}
要使用这个,我必须
delete from [Order] where orderId = ? and version = ?
如果没有删除,则抛出StaleObjectStateException
更新
我发现有两种方法应该有效。这两种方法中的一种有问题吗?第二种方法涉及到较少的数据库访问。客户端通常一次只发送一个要删除的订单,因此性能不应该成为问题
方法1
对于每个要删除的订单:
Order order = orderRepository.findById(
orderIdFromClient).orElseThrow(() ->
new OptimisticLockException());
if (!order.getVersion().equals(versionFromClient)) {
throw new OptimisticLockException();
}
// We now know the managed entity has the same version
// as the requested version. If some other transaction
// has changed the entity, Hibernate will rollback and
// throw OptimisticLockException.
orderRepository.delete(order);
int x = orderRepository.deleteByIdAndVersion(orderIdFromClient, versionFromClient);
if (x==0) {
throw new OptimisticLockException();
}
方法2
添加OrderRepository方法:
int-deleteByIdAndVersion(长id,整数版本);
对于每个要删除的订单:
Order order = orderRepository.findById(
orderIdFromClient).orElseThrow(() ->
new OptimisticLockException());
if (!order.getVersion().equals(versionFromClient)) {
throw new OptimisticLockException();
}
// We now know the managed entity has the same version
// as the requested version. If some other transaction
// has changed the entity, Hibernate will rollback and
// throw OptimisticLockException.
orderRepository.delete(order);
int x = orderRepository.deleteByIdAndVersion(orderIdFromClient, versionFromClient);
if (x==0) {
throw new OptimisticLockException();
}