【快学springboot】8.JPA乐观锁OptimisticLocking
介绍
当涉及到企业应用程序时,正确地管理对数据库的并发访问是至关重要的。为此,我们可以使用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的更多相关文章
- 【快学springboot】13.操作redis之String数据结构
前言 在之前的文章中,讲解了使用redis解决集群环境session共享的问题[快学springboot]11.整合redis实现session共享,这里已经引入了redis相关的依赖,并且通过spr ...
- 【快学SpringBoot】Spring Cache+Redis实现高可用缓存解决方案
前言 之前已经写过一篇文章介绍SpringBoot整合Spring Cache,SpringBoot默认使用的是ConcurrentMapCacheManager,在实际项目中,我们需要一个高可用的. ...
- 【快学springboot】12.实现拦截器
前言 之前在[快学springboot]6.WebMvcConfigurer配置静态资源和解决跨域里有用到WebMvcConfigurer接口来实现静态资源的映射和解决跨域请求,并且在文末还说了Web ...
- 【快学springboot】4.接口参数校验
前言 在开发接口的时候,参数校验是必不可少的.参数的类型,长度等规则,在开发初期都应该由产品经理或者技术负责人等来约定.如果不对入参做校验,很有可能会因为一些不合法的参数而导致系统出现异常. 上一篇文 ...
- 【快学springboot】7.使用Spring Boot Jpa
jpa简介 Jpa (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范.它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据. ...
- Springboot分别使用乐观锁和分布式锁(基于redisson)完成高并发防超卖
原文 :https://blog.csdn.net/tianyaleixiaowu/article/details/90036180 乐观锁 乐观锁就是在修改时,带上version版本号.这样如果试图 ...
- 【快学SpringBoot】快速上手好用方便的Spring Cache缓存框架
前言 缓存,在开发中是非常常用的.在高并发系统中,如果没有缓存,纯靠数据库来扛,那么数据库压力会非常大,搞不好还会出现宕机的情况.本篇文章,将会带大家学习Spring Cache缓存框架. 原创声明 ...
- 【快学SpringBoot】SpringBoot+Docker构建、运行、部署应用
前言 Docker技术发展为当前流行的微服务提供了更加便利的环境,使用SpringBoot+Docker部署和发布应用,其实也是一件比较简单的事情.当前,前提是得有Docker的基础. 源码在文末 文 ...
- 【快学springboot】SpringBoot整合Mybatis Plus
原创声明 本文首发于头条号[Happyjava].Happy的掘金地址:https://juejin.im/user/5cc2895df265da03a630ddca,Happy的个人博客:http: ...
随机推荐
- HDU 4825 Xor Sum(字典树)
嗯... 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825 这道题更明确的说是一道01字典树,如果ch[u][id^1]有值,那么就向下继续查找/ ...
- 火爆微信朋友圈的Excel速成班视频课程
Excel速成班视频课程,一共有10节课,附带课件. 目录结构如下: 目录:/2020032-Excel速成班视频 [4.6G] ┣━━课件 [1.9M] ┃ ┣━━第八课Excel实用技巧12例.x ...
- JavaScript - 代码片段,Snippets,Gist
求n个数字的累加和 递归实现 function getSum(x) { if (x == 1) { return 1; } return x + getSum(x - 1); } var result ...
- 数据表损坏:Incorrect key file for table
最近做项目过程中,调用数据库内容,老是出现一些类似于数据表损坏的提示信息(Incorrect key file for table edison_category),查询不到数据,很是恼火,后来冷静下 ...
- Python NumPy中数组array.min(0)返回数组
如果没有参数min()返回一个标量,如果有参数0表示沿着列,1表示沿着行.
- 2019牛客暑期多校训练营(第十场) Han Xin and His Troop (高精度+拓展中国剩余定理)
题意 裸题 思路 题中的模数之间并不互质,所以应该用拓展中国剩余定理. 但是交上去会炸,__int128过不了,所以用高精度的板子或者java大数都挺好过的. 这里推荐java大数,因为高精度板子用起 ...
- PyQt5四大布局方式
1.绝对布局方式'''绝对布局方式,通过move的XY坐标方式来控制控件的位置'''from PyQt5.QtWidgets import *import sys,math class absolut ...
- 任意值运动框架Move模块 js
function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name]; } else { retur ...
- 解决maven 在intellij IDEA 下载依赖包速度慢的问题
解决maven 在intellij IDEA 下载依赖包速度慢的问题 参考:https://www.jianshu.com/p/63a593700ebc
- 几个原生js知识
1.document.documentElement 返回根节点 html. 2.原生方法获取一个对象的某个样式的值. function getStyle(obj, attr) { if(obj.cu ...