java jpa 异步编程

几年前,在Java世界中,几乎显而易见的是,每个“企业”类项目都需要JPA与数据库进行通信。 JPA是Joel Spolsky描述的“ 泄漏抽象 ”的完美示例。 刚开始时很棒而又容易,但是最后很难调整和限制。 对于许多参与数据访问层的后端开发人员而言,日常工作是黑客并直接使用缓存,刷新和本机查询。 有足够的问题和变通办法来写一本专门的书“面向黑客的JPA”,但是在本文中,我将仅关注并发实体处理。

让我们假设这种情况:我们有一个Person实体,该实体在某些业务流程中由某些服务更新。

@Entity
public class Person {@Id@GeneratedValueprivate Long id;private String uuid = UUID.randomUUID().toString();private String firstName;private String lastName;// getters and setters}

为了忽略任何域的复杂性,我们正在谈论更新此人的名字和姓氏。 我们可以想象代码如下:

firstNameUpdater.update(personUuid, "Jerry");
lastNameUpdater.update(personUuid, "Newman");

经过一段时间的业务决定,这两个元素的更新都花了太长时间,因此减少持续时间成为了头等大事。 当然,有很多不同的方法可以做到这一点,但让我们假设,这种特殊情况并发将解决我们的难题。 这似乎很容易-只需使用Spring和voilà中的@Async注释我们的服务方法即可解决问题。 真? 根据乐观锁定机制的使用,我们这里有两个可能的问题。

  • 使用乐观锁定,几乎可以肯定,我们将从其中一种更新方法中获得OptimisticLockException-一种将排名第二的方法。 与根本不使用乐观锁定相比,这种情况更好。
  • 没有版本控制,所有更新将毫无例外地完成,但是从数据库加载更新的实体后,我们将仅发现一个更改。 为什么会这样呢? 两种方法都更新了不同的字段! 为什么第二笔交易覆盖了其他更新? 由于泄漏的抽象:)

我们知道,Hibernate正在跟踪对我们实体所做的更改(称为脏检查)。 但是为了减少编译查询所需的时间,默认情况下,它在更新查询中包括所有字段,而不是仅包含已更改的字段。 看起来很奇怪? 幸运的是,我们可以将Hibernate配置为以其他方式工作,并根据实际更改的值生成更新查询。 可以使用@DynamicUpdate批注启用它。 这可以看作是部分更新问题的解决方法,但是您必须记住这是一个折衷方案。 现在,此实体的每次更新都比以前更耗时。

现在让我们回到乐观锁定的情况。 坦白地说,我们想要做的通常与这种锁定的想法相反,这种锁定假定实体不会同时进行任何修改,并且当这种情况发生时会引发异常。 现在我们肯定要进行并发修改! 作为一种快速的解决方法,我们可以从锁定机制中排除这两个字段( firstNamelastName )。 可以通过在每个字段上添加@OptimisticLock(excluded = true)来实现。 现在,更新名称将不会触发版本增加-它将保持不变,这当然可能是造成许多麻烦且难以发现一致性问题的原因。
最后但并非最不重要的解决方案是旋转更改。 要使用它,我们必须用循环包装更新逻辑,当OptimisticLock发生时,该逻辑在事务处理时更新。 效果越好,进程中涉及的线程越少。 所有这些解决方案的源代码都可以在我的GitHub的jpa-async-examples存储库中找到 。 只是探索提交。

等待-仍然没有适当的解决方案? 实际上没有。 由于使用了JPA,我们对并发修改问题的简单解决方案不屑一顾。 当然,我们可以重塑我们的应用程序以引入一些基于事件的方法,但是上面我们仍然有JPA。 如果我们使用域驱动设计,则尝试通过使用OPTIMISTIC_FORCE_INCREMENT锁定来关闭整个聚合,只是为了确保更改复合实体或向集合中添加元素会更新整个聚合,因为它应保护不变量。 那么,为什么不使用任何直接访问工具,例如JOOQ或JdbcTemplate呢? 这个主意很棒,但不幸的是,不能与JPA同时使用。 JOOQ所做的任何修改都不会自动传播到JPA,这意味着会话或缓存可能包含过时的值。

为了正确解决这种情况,我们应该将此上下文提取到单独的元素中,例如new table,它将直接由JOOQ处理。 您可能已经注意到,在SQL中进行这种并发更新非常容易:

update person set first_name = "Jerry" where uuid = ?;

使用JPA抽象,它变成了非常复杂的任务,需要对Hibernate行为以及实现内部有深刻的了解。 综上所述,我认为JPA没有遵循“React式”方法。 它是为解决某些问题而构建的,但是目前我们提出了不同的问题,而在许多应用程序中,持久性并不是其中之一。

翻译自: https://www.javacodegeeks.com/2015/11/jpa-in-case-of-asynchronous-processing.html

java jpa 异步编程

java jpa 异步编程_异步处理时的JPA相关推荐

  1. Java Review - 并发编程_ 回环屏障CyclicBarrier原理源码剖析

    文章目录 Pre 小Demo 类图结构 CyclicBarrier核心方法源码解读 int await() int await(long timeout, TimeUnit unit) int dow ...

  2. Java Review - 并发编程_读写锁ReentrantReadWriteLock的原理源码剖析

    文章目录 ReentrantLock VS ReentrantReadWriteLock 类图结构 非公平的读写锁实现 写锁的获取与释放 void lock() void lockInterrupti ...

  3. Java Review - 并发编程_原子操作类LongAdder LongAccumulator剖析

    文章目录 概述 小Demo 源码分析 重要的方法 long sum() reset sumThenReset longValue() add(long x) longAccumulate(long x ...

  4. java future_Java并发编程之异步Future机制的原理和实现

    Java并发编程之异步Future机制的原理和实现 项目中经常有些任务需要异步(提交到线程池中)去执行,而主线程往往需要知道异步执行产生的结果,这时我们要怎么做呢?用runnable是无法实现的,我们 ...

  5. python2异步编程_最新Python异步编程详解

    我们都知道对于I/O相关的程序来说,异步编程可以大幅度的提高系统的吞吐量,因为在某个I/O操作的读写过程中,系统可以先去处理其它的操作(通常是其它的I/O操作),那么Python中是如何实现异步编程的 ...

  6. 深入理解python异步编程_深入理解Python异步编程

    1 什么是异步编程 1.1 阻塞程序未得到所需计算资源时被挂起的状态. 程序在等待某个操作完成期间,自身无法继续干别的事情,则称该程序在该操作上是阻塞的. 常见的阻塞形式有:网络I/O阻塞.磁盘I/O ...

  7. dart异步编程_如何通过期货将一些异步编程引入Dart

    dart异步编程 by Mohammed Salman 穆罕默德·萨尔曼(Mohammed Salman) 如何通过期货将一些异步编程引入Dart (How to bring a little asy ...

  8. python3异步编程_协程 Python异步编程(asyncio)

    协程(Coroutine) 也可以被称为微线程,是一种用户态内的上下文切换技术.简而言之,其实就是通过一个线程实现代码块相互切换执行. 直接上代码,例如: 同步编程 import time def f ...

  9. 同步等待 异步等待_异步/等待与承诺互操作性

    同步等待 异步等待 Usually, when discussing Promises and async/await syntax, people frame it as an "eith ...

最新文章

  1. 原 CNCF 执行董事 Dan Kohn 辞世,沉痛哀悼
  2. 32位处理器的寄存器介绍
  3. 2017网易校招真题 合唱团
  4. C#中访问私有成员技巧
  5. Linux 下安装配置redis
  6. mysql改变地址_mysql 修改数据库存储地址
  7. Python开课复习10
  8. java double方法_Java Double类compare()方法与示例
  9. 1-9月全国快递服务企业业务量累计完成561.4亿件 同比增长27.9%
  10. 数据库一些开发者了解的操作
  11. MySql基本的语法(学习笔记)
  12. Everything 中文绿色版
  13. AS3文本框的操作,为密码框添加按钮
  14. web压力测试工具(小而精)
  15. win10系统64位安装与配置java环境,安装使用citespace经验
  16. 量子力学在计算机上的应用论文,量子力学论文.doc
  17. 在使用变量的时候,双引号和单引号 如何使用,及其区别:
  18. 511遇见易语言文本处理寻找文本
  19. iOS学习笔记-018.舒尔特表游戏
  20. 类脑计算芯片作为基础前沿技术重大突破成果,荣登CCTV《新闻联播》

热门文章

  1. 【DP】【容斥】Nice to Meet You(AT3634)
  2. 【倍增】【线段树】雨林跳跃(luogu 7599[APIO 2021 T2])
  3. 裁缝师(2011特长生 T2)
  4. [XSY4197] Snow(树形DP)
  5. 14、mysql中事务的应用
  6. Hadoop入门(十九)Mapreduce的最大值程序
  7. 如何快速搭建一个免费的,无限流量的Blog
  8. MySQL year()函数
  9. 一个多线程死锁案例,如何避免及解决死锁问题
  10. Docker部署运行微服务