异步处理时的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没有遵循“反应式”方法。 它是为解决某些问题而构建的,但是目前我们提出了不同的问题,而在许多应用程序中,持久性并不是其中之一。

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

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

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

相关文章

又见链表 --- 另一种Creat方式与反转

链表 作为一种数据结构,链表以其方便的增删查改功能,实现了无数经典有用的程序。 在之前的帖子里,我构建链表的方式是建立一个不储存数据的head节点,然后通过一边输入数据一边建立结点的方式构建整个链表。 与之前不同的是&#x…

Hystrix简介–总结

这是其他两篇文章的后续文章– 动机 ,说明为什么在分布式系统中需要类似Hystrix的内容,以及Hystrix的基本介绍 。 这将是我的Hystrix旅程的总结,其中包含各种属性的详细信息,可以对这些属性进行调整以更改Hystrix的行为&#xff…

git常用命令有用

http://www.cnblogs.com/cspku/articles/Git_cmds.html转载于:https://www.cnblogs.com/yanjunhelloworld/p/5507706.html

现在抖音这么火,那么你知道如何用CSS实现抖音字体?

比如这种抖音字体是不是感觉很酷,它是如何实现的呢,下面孙叫兽就简单分享一下CSS的实现方法,记得点赞收藏。 老司机给大家的一些小建议,一定要敲代码敲代码敲代码(重要的事情说三遍),程序员是实战家,不是思想家和理论家,程序员都是工兵,这个排雷的经验很重要。 实现这…

史上最全关于苹果开发者账号及上架APPStore总结

很多人如果开发这种移动应用APP,上架到到APPStore难免会遇到一系列的问题,这里孙叫兽进行总结一下,如果本文对你有帮助,记得转发点赞收藏。 一: 开发者账号的介绍 1 个人开发者账号 申请费用: 99美元/年 介绍:一般由iOS开发者个人申请,上架开发者自己的APP作品到苹果商…

EK算法应用,构图(POJ1149)

题目链接:http://poj.org/problem?id1149 题意中有一点要注意,否则构图就会有问题,每个顾客走后,被打开过的那些猪圈中的猪都可以被任意的调换到其他开着的猪圈中。 这里的构图不是单一的相邻,以及容量了,…

平台代码检查工具:sonarLint+sonarqube安装教程

加强对代码质量的管控要求,不允许新增代码部分出现严重、重要、主要等sonar扫描问题。 大家按以下文档安装开发工具对应的代码检测插件,请大家务必重视、执行.这里只介绍前端开发VSCode,后端开发Eclipse,两种代表性的编译器安装sonarLintsonarqube方法,其…

jboss as安装配置_书评:JBoss AS 7:配置,部署和管理

jboss as安装配置我热切地接受Packt Publishing邀请复审JBoss AS 7:配置,部署和管理,因为自从我上次使用JBoss已有数年了,我很想了解有关JBoss AS 7的更多信息。 我已经写过关于《 JBoss AS 7配置,部署和管理》一书的第…

程序员通过CSDN如何获取收益

大家好,我是孙叫兽 ,本期内容给大家分享如何使用CSDN一边学习,一遍赚取收益,这样学习的时候也会产生动力. 废话不多说,直接看近7天收益. 博主如何赚取收益 对于博主这些创作者来说,收益主要有付费专栏,VIP文章收益,活动收益,红包收益,问答收益,打赏收益,付费资源收益,下载VIP分…

在Java8中包装设计模式

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

《Windows驱动开发技术详解》之编程加载NT式驱动

之前我们加载驱动都是利用INSTDRV这个应用,其原理是在注册表中写入相应的字段,这一节我们手动编写代码去加载驱动,其原理类似: 设备驱动程序的动态加载主要由服务控制管理程序(Service Control Manager,SCM&#xff09…

教你如何成为解决问题的高手

最近看到很多初级或者准备入坑的小伙伴在问答模块提问问题 ,有的在QQ群或者微信群提问题,这个是很多新手程序员都会经历的一个过程,这种事情很正常,主要是自己都不清楚问题是什么或者描述不清楚,别人如何帮你解答呢? 目录 1.澄清问题 2.关联经验 3.问题重现 4.寻找差异 5…

mongodb存储数据_在MongoDB中存储分层数据

mongodb存储数据继续使用MongoDB进行 NoSQL之旅,我想谈一谈一个经常出现的特定用例:存储分层文档关系。 MongoDB是很棒的文档数据存储,但是如果文档具有父子关系,该怎么办? 我们可以有效地存储和查询此类文档层次结构吗…

程序员如何快速成长为IT精英

很多程序员工作了很多年,仍然只学到了皮毛点的业务和技术,技术长时间没有提升,一直拖拖拉拉处于某个水平,没有接触到核心业务,也难于成为公司的中流砥柱和骨干。那么程序员该如何成长呢? 1.主动学习 时刻保持危机感,对知识保持好奇心,完善自己的职业规划和知识体系,掌…

hdu1521 指数型母函数

排列组合 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3438 Accepted Submission(s): 1439Problem Description有n种物品,并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品…

【Java从入门到天黑|06】高质量男性SpringBoot入门及原理(基础总结版,强烈建议收藏)

目录 SpringBoot简介 Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。 helloWorld

JavaFX实际应用程序:AISO HRC-Matic

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

Feather包实现数据框快速读写,你值得拥有

什么是Feather? Feature是一种文件格式,支持R语言和Python的交互式存储,速度更快。目前支持R语言的data.frame和Python pandas 的DataFrame。 Feather收到了Apache arrow 项目的支持,Apache Arrow是Apache基金会下一个全新的开源项…

一文教你学会需求分析与管理

大家好,我是孙叫兽,本期给大家分享需求分析与管理,在项目开始或者需求整理时,这方面的知识显得尤为重要,常言道:良好的开始是成功的一半! 1.需求的定义 产品需求是在一定的时期,一定的场景中,无论是心理上还是生理上的,用户有着某种“需要”,这种“需要”用户自己不…

java 编写代码_Java 7:如何编写非常快速的Java代码

java 编写代码当我第一次写此博客时,我的目的是向您介绍ThreadLocalRandom类,它是Java 7中新增的用于生成随机数的类。 我在一系列微基准测试中分析了ThreadLocalRandom的性能,以了解其在单线程环境中的性能。 结果相对令人惊讶:尽…