java jpa 异步编程_异步处理时的JPA

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 异步编程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言字符数组与字符串的使用详解

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删正文1、字符数组的定义与初始化字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素。char str[10]{ I, ,a,m, ,‘h,a,p…

SRC挖洞网集合

阿里SRC https://security.alibaba.com/ 蚂蚁集团SRC https://security.alipay.com/ 阿里本地生活SRC https://asrc.alibaba.com/#/ 京东安全应急响应中心 https://security.jd.com/#/ 腾讯SRC https://security.tencent.com/ 美团安全应急响应中心 https://security.meit…

不能将紧实的字段 绑定到_代码整洁之道【笔记】

一、整洁代码A.混乱的代价1.有些团队在项目初期进展迅速,但有那么一两年的时间却慢去蜗行。对代码的每次修改都影响到其他两三处代码2.花时间保持代码整洁不但有关效率,还有关生存3.程序员遵从不了解混乱风险经理的意愿,也是不专业的做法4.Bj…

存根类 测试代码 java_测试双打:模拟,假人和存根

存根类 测试代码 java大多数班级都有合作者。 在进行单元测试时,您通常希望避免使用那些协作者的实际实现方式来避免测试的脆弱性和绑定/耦合,而应使用测试双打:模拟,存根和双打。 本文引用了有关该主题的两篇现有文章&#xff1…

5 个牛逼的算法设计,你知道几个?

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删1、分治法概念:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之…

python2.7.10安装教程_Linux系统(CentOS)下python2.7.10安装

本文记录了Linux系统(CentOS)安装Python,供大家参考,具体内容如下Python(Linux) 下载地址操作系统:Centos6.41、下载下载的版本:Python-2.7.10.tgz2、安装一般情况下,Linux都会预装 Python了,但版本较低。(…

javafx窗体程序_JavaFX实际应用程序:AISO HRC-Matic

javafx窗体程序“ Real-World JavaFX Apps”系列中的第三个应用程序是一种重型数据输入应用程序,由称为HRC-Matic的关系数据库支持。 它由AISO在日内瓦开发。 AISO是一家专门开发基于JavaFX的业务应用程序的公司。 他们还在研究我在本系列的第一个博客( …

x201换风扇_笔记本怎么换风扇 ThinkPad X201i换风扇图文教程

ThinkPad X201i换电扇图文教程:拆机之前,我们需求先对X201i的散热电扇在停止了开端的理解,得知价钱从10元左右的单电扇,到上百的散热全体都有,而且还分东芝产和松下产等不同产地的,小编选择了松下产的整套散…

几十个Shell分析日志文件脚本!

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删收集,整理一些服务器日志分析命令,可以用来分析自己网站服务器日志, 看看网站的访问量。看看有没有黑阔搞破坏…

flex布局水平垂直 垂直_垂直和水平装饰

flex布局水平垂直 垂直装饰器模式是在不更改其接口的情况下向对象添加功能的最佳方法之一。 我经常使用可组合装饰器,并且总是会问自己在功能列表必须可配置时如何正确设计它们。 我不确定我的答案是否正确,但是这里有一些值得深思的地方。 The Apartme…

一文读懂 | Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删栈是什么?栈有什么作用?首先,栈 (stack) 是一种串列形式的数据结构。这种数据结构的特点是后入先出 (LIFO, L…

thinkphp6企业项目实战_[MarsZ]ThinkPHP项目实战总结

本文原word格式百度云盘下载地址:综述 2需求 2作者 2系统一览 2Unity3d客户端 2PHP后台 4准备 6XAMPP 6官网 6下载地址 6教程 6ThinkPHP 6官网 7项目所用版本 7下载地址 7快速入门 7完全手册 7步骤 7准备ThinkPHP 7修改MySQL设置信息 8检测是否成功 9扩展&#xff1…

java包装模式_在Java8中包装设计模式

java包装模式GOF书中没有列出环绕模式,但对于以下问题非常有用: 循环构造,例如执行while / while / for循环 秒表周围的一些代码。 用运行时异常包装检查的异常 初始化和清理,例如创建/销毁线程池或打开/关闭文件等 将上下文…

c得到当前时分秒 linux_Linuxc - Linux系统下的时间知识点

Unix/Linux系统下的时间知识点一、Unix/Linux系统的几种时间结构:1、time_t 类型:长整型,一般用来表示从1970-01-01 00:00:00时以来的秒数,精确度:秒;由函数time()获取;该类型定义在头文件 /usr…

【C语言】彻底搞懂内存屏障与volatile

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删最有价值的写在最前面内存屏障与 volatile 是高并发编程中比较常用的两个技术,无锁队列的时候就会用到这两项技术。然而这两项技术涉…

javafx 使用_何时使用JavaFX代替HTML

javafx 使用像我这样的JavaFX爱好者反复面对的一个问题是何时(或为什么)使用JavaFX代替HTML(5)。 这是我的两分钱: 如果…,则应使用JavaFX。 …您对坚固性/质量感兴趣。 JavaFX是Java! 您将能…

charles代理手机调试_H5开发 移动端 调试之 Charles 抓包 和 Map Remote

移动端调试是每一位前端工程师必须掌握的技能,在移动端环境上往往有很多不同的情况,我们需要借助一些工具来调试。本文将介绍 Mac 如何安装 charles,进行抓包、以及一些应用场景。场景一:app端内线上环境接口报错,想看…

lucene 查询示例_Lucene查询(搜索)语法示例

lucene 查询示例本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中,您将了解Lucene。 您将了解为什么这样的库很重要,然后了解Lucene中搜索的工作方式。 此外,您将学习如何将Lucene Search集成到您自己的应用程序中…

熟悉又陌生的arm 编译器详解(armcc/armclang)

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删arm编译器学习首先来了解一下编译器,其通常分为三个部分:前端优化器后端。前端:词法、语法和语义分析&#x…

js怎么获取一个元素与屏幕右边的距离_js如何获取div(ul li)离屏幕上下左右边距离(长度)...

在网页中移到元素div(或 ul li),常常需要获取元素div离屏幕上下左右的距离,这样可以知道元素处在屏幕中的位置,以控制元素的移动。获取元素div的长度或高度,可以用 js 获取元素div的width或height属性得到,但元素没有距…