gpt4 book ai didi

spring-boot - spring-boot 项目中版本更改时未抛出 OptimisticLockException

转载 作者:行者123 更新时间:2023-12-04 16:09:55 26 4
gpt4 key购买 nike

模型结构:

@MappedSuperclass
public class BaseModel<K extends Comparable> implements Serializable, Comparable<Object> {

private static final long serialVersionUID = 1L;

@Id
private K id;

@Version
private Integer version;

// getter/setter
}

@Entity
public class MyEntity extends BaseModel<String> {
// some fields and it's getter/setter
}

my_entity 在我的数据库中记录:

id: 1版本:1...

以下是我的更新方法:

void update(String id, Integer currentVersion, ....) {
MyEntity myEntity = myRepository.findOne(id);
myEntity.setVersion(currentVersion);
// other assignments

myRepository.save(myEntity);
}

以下是调用此方法时触发的查询。

update my_entity set version=?, x=?, y=?, ...
where id=? and version=?

当上述方法中传递的 currentVersion 不是 1 时,我期待 OptimisticLockException。

任何人都可以帮助我为什么我没有收到 OptimisticLockException 吗?我正在为我的 webmvc 项目使用 spring-boot。

最佳答案

JPA 规范的第 11.1.54 节指出:

In general, fields or properties that are specified with the Version annotation should not be updated by the application.

根据经验,如果您尝试手动更新版本字段,我可以建议某些 JPA 提供程序(OpenJPA 就是其中之一)实际上会引发异常。

虽然不能严格回答您的问题,但您可以进行如下重构,以确保 JPA 提供者之间的可移植性和严格遵守 JPA 规范:

public void update(String id, Integer currentVersion) throws MyWrappedException {
MyEntity myEntity = myRepository.findOne(id);

if(currentVersion != myEntity.getVersion()){
throw new MyWrappedException();
}

myRepository.save(myEntity);

//still an issue here however: see below
}

假设您的 update(...) 方法正在事务中运行,但是您仍然对上述 JPA 规范说明的第 3.4.5 节有问题:

3.4.5 OptimisticLockException Provider implementations may defer writing to the database until the end of the transaction, when consistent with the lock mode and flush mode settings in effect. In this case, an optimistic lock check may not occur until commit time, and the OptimisticLockException may be thrown in the "before completion" phase of the commit. If the OptimisticLockException must be caught or handled by the application, the flush method should be used by the application to force the database writes to occur. This will allow the application to catch and handle optimistic lock exceptions.

基本上,2 个用户可以为同一个实体提交并发修改。两个线程都可以通过初始检查,但是当更新刷新到可能处于事务提交的数据库时,即在您的方法完成之后,一个线程将失败。

为了捕获和处理 OptimisticLock 异常,您的代码应如下所示:

public void update(String id, Integer currentVersion) throws MyWrappedException {
MyEntity myEntity = myRepository.findOne(id);

if(currentVersion != myEntity.getVersion()){
throw new MyWrappedException();
}

myRepository.save(myEntity);

try{
myRepository.flush()
}
catch(OptimisticLockingFailureException ex){
throw new MyWrappedException();
}
}

关于spring-boot - spring-boot 项目中版本更改时未抛出 OptimisticLockException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30098350/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com