介绍

当涉及到企业应用程序时,正确地管理对数据库的并发访问是至关重要的。为此,我们可以使用Java Persistence API提供的乐观锁定机制。它导致在同一时间对同一数据进行多次更新不会相互干扰。为了使用OptimisticLocking,我们需要一个实体(Entity),其中包含一个带有@Version注释的属性。在使用它时,每个读取数据的事务都持有version属性的值。在事务想要进行更新之前,它将再次检查version属性。如果值在此期间发生了更改,则抛出ObjectOptimisticLockingFailureException。否则,事务提交update并递增version的值。这种机制适用于读操作比更新或删除操作多得多的应用程序。

新建一个UserEntity.java

@Entity
@Table(name = "user")
@Data
@OptimisticLocking
public class User { @Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Integer id; @Column(name = "username", unique = true, nullable = true, length = 50)
private String username; private String password; @Version
private Integer version; @PrePersist
public void prePersist() {
version = 0;
} }

spring data jpa在上一篇文章已经做过一些讲解了【快学springboot】7.使用Spring Boot Jpa。感兴趣的朋友可以看看。这里定义了一个version字段,使用了Version注解标识。PrePersist这个注解表示在新增数据之前执行。

新建UserRepo接口

public interface UserRepo extends PagingAndSortingRepository<User, Integer>, JpaSpecificationExecutor<User> {

}

新建一个UserTest类,继承SpringbootApplicationTests

public class UserTest extends SpringbootApplicationTests {

}

SpringbootApplicationTests这个类是使用Spring initialize新建项目的时候自动生成的用来做单元测试的类。在UserTest上注入UserRepo,并且写一个新增user的单测。

执行之后查看数据库。

该记录已经被创建出来了。

测试update该记录

执行后查看数据库:

可以看到version字段自增了1。

测试JPA乐观锁

新建一个方法,如下

这里查询了两次id为1的记录,然后分别更新了这条记录。根据前面的描述,这里会抛出一个ObjectOptimisticLockingFailureException异常。启动测试,结果如下:

这是符合预期的。看下数据库的version,在这种情况下,我们的预期结果是version变为2。

通过数据库的值查看,测试都是符合预期的。

去掉User的OptimisticLocking注解

我们把User实体的OptimisticLocking注解去掉,然后再次执行上面的方法。

这一次程序顺利执行了,然后查看下数据库的记录:

预期应该是version会变为3,然后username变为happyjava-new2。

通过结果来看,这是符合预期的。

总结

spring data jpa通过OptimisticLocking实现了乐观锁,该乐观锁不是通过数据库自身去实现的,它是通过version字段(需要Version注解标识)去实现的。如果update的数据时候,发现数据库的version大于等于当前的version,则会抛出ObjectOptimisticLockingFailureException,错误信息是

Row was updated or deleted by another transaction

【快学springboot】8.JPA乐观锁OptimisticLocking的更多相关文章

  1. 【快学springboot】13.操作redis之String数据结构

    前言 在之前的文章中,讲解了使用redis解决集群环境session共享的问题[快学springboot]11.整合redis实现session共享,这里已经引入了redis相关的依赖,并且通过spr ...

  2. 【快学SpringBoot】Spring Cache+Redis实现高可用缓存解决方案

    前言 之前已经写过一篇文章介绍SpringBoot整合Spring Cache,SpringBoot默认使用的是ConcurrentMapCacheManager,在实际项目中,我们需要一个高可用的. ...

  3. 【快学springboot】12.实现拦截器

    前言 之前在[快学springboot]6.WebMvcConfigurer配置静态资源和解决跨域里有用到WebMvcConfigurer接口来实现静态资源的映射和解决跨域请求,并且在文末还说了Web ...

  4. 【快学springboot】4.接口参数校验

    前言 在开发接口的时候,参数校验是必不可少的.参数的类型,长度等规则,在开发初期都应该由产品经理或者技术负责人等来约定.如果不对入参做校验,很有可能会因为一些不合法的参数而导致系统出现异常. 上一篇文 ...

  5. 【快学springboot】7.使用Spring Boot Jpa

    jpa简介 Jpa (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范.它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据. ...

  6. Springboot分别使用乐观锁和分布式锁(基于redisson)完成高并发防超卖

    原文 :https://blog.csdn.net/tianyaleixiaowu/article/details/90036180 乐观锁 乐观锁就是在修改时,带上version版本号.这样如果试图 ...

  7. 【快学SpringBoot】快速上手好用方便的Spring Cache缓存框架

    前言 缓存,在开发中是非常常用的.在高并发系统中,如果没有缓存,纯靠数据库来扛,那么数据库压力会非常大,搞不好还会出现宕机的情况.本篇文章,将会带大家学习Spring Cache缓存框架. 原创声明 ...

  8. 【快学SpringBoot】SpringBoot+Docker构建、运行、部署应用

    前言 Docker技术发展为当前流行的微服务提供了更加便利的环境,使用SpringBoot+Docker部署和发布应用,其实也是一件比较简单的事情.当前,前提是得有Docker的基础. 源码在文末 文 ...

  9. 【快学springboot】SpringBoot整合Mybatis Plus

    原创声明 本文首发于头条号[Happyjava].Happy的掘金地址:https://juejin.im/user/5cc2895df265da03a630ddca,Happy的个人博客:http: ...

随机推荐

  1. 基于SILVACO ATLAS的a-IGZO薄膜晶体管二维器件仿真(06)

    在知网看到了江南大学的硕士论文: 双有源层a-IGZO薄膜晶体管的特性仿真 IGZO/IZO双有源层薄膜晶体管特性的模拟研究 发现,我昨天的文章中参数的设置存在重大失误,如下材料定义语句中: mate ...

  2. Spring boot security权限管理集成cas单点登录

    挣扎了两周,Spring security的cas终于搞出来了,废话不多说,开篇! Spring boot集成Spring security本篇是使用spring security集成cas,因此,先 ...

  3. 爬虫(十三):PIL模块

    1. PIL模块 在爬虫(十二):图形验证码的识别.滑动验证码的识别(B站滑动验证码)中我留下了一个悬念,为什么安装的是pillow模块,而不是PIL模块.这是因为PIL是python2的产物,它并没 ...

  4. Mybatic逆向工程的使用

    前言:利用别人的方法.知识.经历或精神成为你自己,不思考不实践不总结不反馈,就不会变成你的. 转载必须表明出处:https://www.cnblogs.com/fby698/p/9463831.htm ...

  5. python opencv:像素操作

    图片的像素 像素:组成图片的单位 RGB:颜色由 RGB三种颜色组成 颜色深度:对于8bit的颜色深度来说,它可以表示的颜色范围是 0 ~ 255,对于RGB图片来说,8位颜色深度可以表示 (2^8) ...

  6. 给Linux安装中文的man手册

    查找 yum list |grep man.*zh 安装 sudo yum install man-pages-zh-CN.noarch 配置 alias cman='man -M /usr//sha ...

  7. c语言中的qsort用法

    1.首先了解 int cmp(const void* a, const void* b) 表示声明cmp函数,其返回值为int型,参数为两个不可修改(const)的void型指针 2.函数原型 函数声 ...

  8. proto school tutorial: blog: lesson 1

    https://proto.school/#/blog/01 我们现在希望:把一个post 和他的作者联系起来. 从之前的教程here中,你可以知道, 一个cid 就是代表一个link 比如: { l ...

  9. Pandas的Categorical Data类型

    pandas从0.15版开始提供分类数据类型,用于表示统计学里有限且唯一性数据集,例如描述个人信息的性别一般就男和女两个数据常用'm'和'f'来描述,有时也能对应编码映射为0和1.血型A.B.O和AB ...

  10. 自定义Redis作为Session存储服务提供

    之前看网上介绍可使用Redis自定义Session托管,使用第三方的Harbour.RedisSessionStateStore GitHub:https://github.com/TheCloudl ...