Spring boot,Spring数据JPA并发访问

问题描述 投票:1回答:2

我正在尝试使用Spring引导和Spring数据JPA创建一个Restful API来执行CRUD操作。该数据库将是Oracle关系数据库。现在可以进行并发访问,如果仅通过@Transactional使用spring事务,那么将满足并发CRUD操作的目的。

我看到有“ JPA乐观和悲观的锁定策略版本”列。我的具体问题是,对于并发CRUD操作,我们是否需要Spring事务和JPA锁定策略?还是仅相应地配置Spring事务就足够了?

spring-boot jpa concurrency spring-data-jpa spring-transactions
2个回答
1
投票

乐观锁是JPA的默认策略。乐观锁定可用于大多数应用程序。乐观锁更加容易和有效。悲观锁需要在类似情况下使用,例如在提交事务之前需要了解Collision。

因此您不需要配置锁定策略。


0
投票

尝试从以下简单的方法开始,使IMO在许多情况下都适用:Optimistic lockingSpring Retry

1)将带有version注释的@Version属性添加到您的实体(例如,您可以在基本抽象实体类中进行此操作,以简化过程):

@Entity
public class MyEntity {

    @Id
    @GeneratedValue
    private Long id;

    @Version
    private Long version;

    // other stuff
}

例如,在这种情况下,当您更新实体时,Hibernate将在更新查询的条件子句中使用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) {
    // ...
}

在这种情况下,如果该方法中出现异常,它将在新事务中再次调用以重复该操作。

附加信息:

© www.soinside.com 2019 - 2024. All rights reserved.