我正在尝试创建一个Restful API,使用Spring boot和Spring data JPA来执行CRUD操作。数据库将是用于并发访问的Oracle关系database.Now,如果我们只使用使用@ transactions的spring事务,这将服务于我们并发CRUD操作的目的。
我看到有JPA乐观和悲观的锁定策略版本栏。我的具体问题是,对于并发CRUD操作,我们是否需要Spring事务和JPA锁定策略?或者只需相应地配置Spring事务就足够了?
发布于 2019-11-21 06:22:37
尝试从以下简单的方法开始,即IMO在许多情况下都适用:带有Spring Retry的Optimistic locking。
1)将带有@Version注释的version属性添加到您的实体中(您可以在基本抽象实体类中进行此操作,例如,为了简化过程):
@Entity
public class MyEntity {
@Id
@GeneratedValue
private Long id;
@Version
private Long version;
// other stuff
}在这种情况下,例如,当您要更新实体时,Hibernate将使用update查询的condition子句中的version属性的当前值,并递增此值以存储实体。例如,一些服务的代码:
@Transactional
public Optional<MyEntity> update(Long id, MyEntity source) {
return myEntityRepository
.findById(id)
.map(target -> mapper.updateEntity(source, target));
}将生成以下SQL查询:
1. select * from my_entities where id = ?;
2. update my_entities set ..., version = <version value from query #1> + 1 where id = ? and version = <version value from query #1>;因此,如果另一个并发进程设法首先更新这个实体,那么您的方法将失败,并返回一个异常(OptimisticLockException)。
2)要管理该方法中的异常,请向其添加@Retryable注释(以及配置或应用程序类上的@EnableRetry注释):
@Retryable(maxAttempts = 2)
@Transactional
public Optional<MyEntity> update(Long id, MyEntity source) {
// ...
}在这种情况下,如果该方法中出现异常,则将在新事务中再次调用该异常,以重复该操作。
其他信息:
发布于 2019-11-20 21:32:51
乐观锁是JPA的默认策略。乐观锁定可用于大多数应用程序。乐观锁更容易、更高效。悲观锁需要在这样的情况下使用,即在提交事务之前需要知道冲突。
因此,您不需要配置锁定策略。
https://stackoverflow.com/questions/58955283
复制相似问题