介绍

当涉及到企业应用程序时,正确地管理对数据库的并发访问是至关重要的。为此,我们可以使用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

最新文章

  1. C# 在執行程式目錄下產生文件夾
  2. mac osx vi 设置tab 四个空格
  3. 如何获取有性能问题的SQL
  4. linux学习之——基础命令
  5. swift 枚举类型
  6. addClass的用法和is函数的用法
  7. 记一次MySQl 安装1067错误
  8. qsort的几种用法
  9. android 中文 api (71) —— BluetoothServerSocket[蓝牙]
  10. win7下wordPress本地搭建博客详解(深度亲测整理---傻瓜式详细教程)
  11. miracl去除某些特殊信息
  12. Java IO流操作汇总: inputStream 和 outputStream【转】
  13. 家庭记账本之微信小程序(七)
  14. Mike and strings 798B
  15. centos 64位 下hadoop-2.7.2 下编译
  16. Window10家庭版启动hyper-v虚拟机组件
  17. 批量合并GDB
  18. 连接oracle服务器超慢--原因分析
  19. python笔记--2018-2019
  20. long polling

热门文章

  1. 360安全浏览器已经完成和统一操作系统UOS的适配工作
  2. jquery Ajax标准规范写法
  3. hadoop学习笔记(一):NameNade持久化和DataNode概念
  4. Fluent_Python_Part4面向对象,11-iface-abc,协议(接口),抽象基类
  5. [0CTF 2016] piapiapia
  6. logback.xml设置mogodb日志打印控制台
  7. 创建DataTable与DataGridView进行绑定
  8. 转专业后对于C语言补修的一些体会(2)
  9. mybatis源码探索笔记-3(使用代理mapper执行方法)
  10. 洛谷 CF804B Minimum number of steps