lock.lock_HibernateCascadeType.LOCK陷阱

lock.lock

介绍

引入了Hibernate 显式锁定支持以及Cascade Types之后 ,就该分析CascadeType.LOCK行为了。

Hibernate锁定请求触发内部LockEvent 。 关联的DefaultLockEventListener可以将锁定请求级联到锁定实体子级。

由于CascadeType.ALL也包括CascadeType.LOCK ,因此当锁定请求从父级实体传播到子级实体时,值得理解。

测试时间

我们将从以下实体模型开始:

注释后详细信息级联

PostPostDetail一对一关联和Comment一对多关联的Parent实体,这些关联用CascadeType.ALL标记:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "post", orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();@OneToOne(cascade = CascadeType.ALL, mappedBy = "post", optional = false, fetch = FetchType.LAZY)
private PostDetails details;

所有即将到来的测试用例将使用以下实体模型图:

doInTransaction(session -> {Post post = new Post();post.setName("Hibernate Master Class");post.addDetails(new PostDetails());post.addComment(new Comment("Good post!"));post.addComment(new Comment("Nice post!"));session.persist(post);
});

锁定管理实体

将受管实体加载到当前正在运行的持久性上下文中,并将所有实体状态更改转换为DML语句。

当托管实体被锁定时:

doInTransaction(session -> {Post post = (Post) session.createQuery("select p " +"from Post p " +"join fetch p.details " +"where " +"   p.id = :id").setParameter("id", 1L).uniqueResult();session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(post);
});

只有实体被锁定,因此可以防止级联:

select id from Post where id = 1 for update

Hibernate定义了一个范围 LockOption ,该范围 (根据JavaDocs)应允许将锁定请求传播到Child实体:

“范围”是JPA定义的术语。 基本上,它是关联锁定的级联。

session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE))
.setScope(true)
.lock(post);

设置范围标志不会改变任何东西,只有被管实体被锁定:

select id from Post where id = 1 for update

锁定独立实体

除了实体锁定之外,锁定请求还可以重新关联分离的实体。 为了证明这一点,我们将在锁定实体请求之前和之后检查Post实体图:

void containsPost(Session session, Post post, boolean expected) {assertEquals(expected, session.contains(post));assertEquals(expected, session.contains(post.getDetails()));for(Comment comment : post.getComments()) {assertEquals(expected, session.contains(comment));}
}

以下测试演示了CascadeType.LOCK如何用于分离的实体:

//Load the Post entity, which will become detached
Post post = doInTransaction(session -> (Post) session.createQuery("select p " +"from Post p " +"join fetch p.details " +"join fetch p.comments " +"where " +"   p.id = :id")
.setParameter("id", 1L)
.uniqueResult());//Change the detached entity state
post.setName("Hibernate Training");
doInTransaction(session -> {//The Post entity graph is detachedcontainsPost(session, post, false);//The Lock request associates //the entity graph and locks the requested entitysession.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(post);//Hibernate doesn't know if the entity is dirtyassertEquals("Hibernate Training", post.getName());//The Post entity graph is attachedcontainsPost(session, post, true);
});
doInTransaction(session -> {//The detached Post entity changes have been lostPost _post = (Post) session.get(Post.class, 1L);assertEquals("Hibernate Master Class", _post.getName());
});

锁定请求重新关联了实体图,但是当前正在运行的Hibernate Session并未意识到实体处于分离状态时变脏了。 仅在不强制执行UPDATE或选择当前数据库状态进行进一步比较的情况下,才重新连接实体。

一旦对实体进行管理, 脏检查机制将检测到任何进一步的更改,并且刷新还将传播重新附加的更改。 如果在管理实体时未发生任何更改,则不会安排该实体进行刷新。

如果我们要确保分离的实体状态始终与数据库同步,则需要使用merge或update 。

scope选项设置为true时,分离的实体传播lock选项:

session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE))
.setScope(true)
.lock(post);

Post实体锁定事件会传播到所有Child实体(因为我们正在使用CascadeType.ALL ):

select id from Comment where id = 1 for update
select id from Comment where id = 2 for update
select id from PostDetails where id = 1 for update
select id from Post where id = 1 for update

结论

锁级联不是直截了当或直观的。 明确锁定需要勤奋(越锁我们获得了,死锁的几率就越大),你最好还是保留对儿童实体锁传播完全控制反正。 类似于并发编程的最佳实践,因此,手动锁定优于自动锁定传播。

  • 代码可在GitHub上获得 。

翻译自: https://www.javacodegeeks.com/2015/03/hibernate-cascadetype-lock-gotchas.html

lock.lock

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

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

相关文章

浅谈面向对象思想下的 C 语言

如何使用OO思维方式面向对象(object Oriented&#xff0c;简称&#xff1a;OO)在于用“找对象”的方式去规划和描述问题。一、怎样“找对象” &#xff08;思维过程&#xff09;“对象”是具有共性的一个群体。以 L298N 控制马达的官方推荐方法为例&#xff0c;控制的共性在于&…

我的世界服务器里怎么无限随机传送,我的世界随机传送插件使用教程 权限指令分享...

导读&#xff1a;在我的世界中玩家可以利用随机传送插件来进行传送人物质与设定点&#xff0c;那么随意传送插件该如何使用呢、下面小编我就来教教各位&#xff0c;我的世界随意传送插件使用教程。什么是RandomLocationRandomLocation让你传送到预设区域的随机位置。可以通过命…

热敏电阻温度特性曲线_NTC热敏电阻如何选型

什么是NTCNTC 热敏电阻是负温度系数的电阻&#xff0c;其特性是电阻值随着温度的升高而呈下降趋势。这个与PTC或者PT100等正温度系数的热敏电阻相反。NTC 热敏电阻NTC的阻值-温度对应曲线如下图所示(100K为例&#xff0c;B值3950)。NTC 热敏电阻R-T曲线下面介绍选型原则。2.根据…

如何使用C语言的面向对象?

我们都知道&#xff0c;C 才是面向对象的语言&#xff0c;但是C语言是否能使用面向对象的功能?(1)继承性typedef struct _parent{int data_parent;}Parent;typedef struct _Child{struct _parent parent;int data_child;}Child;在设计C语言继承性的时候&#xff0c;我们需要做…

netflix_学习Netflix管理员–第2部分

netflix为了继续上一篇有关Netflix Governator的一些基础知识的文章&#xff0c;在这里&#xff0c;我将介绍Netflix Governator带给Google Guice的另一项增强功能–生命周期管理 生命周期管理本质上提供了进入对象所经历的不同生命周期阶段的钩子&#xff0c;以引用有关Gover…

t3软件怎么生成报表_临沂用友畅捷通T3财务通软件财税一体化

用友T3财税通针对财税一体化的发展趋势&#xff0c;在用友通上海财税专版的基础上&#xff0c;经过完善和提高。同时加入了税务核算功能、所得税汇算功能。 财税通财务软件的财税同步处理&#xff0c;可将事后税务处理的汇总涉税数据工作化整为零&#xff0c;分解到日常凭证填制…

每日干货丨C语言知识总结----循环结构

介绍循环结构可以看成是一个条件判断语句和一个向回 转向语句 的组合。另外&#xff0c;循环结构的三个要素&#xff1a;循环变量、 循环体 和循环终止条件. &#xff0c;循环结构在 程序框图 中是利用判断框来表示&#xff0c;判断框内写上条件&#xff0c;两个出口分别对应着…

apache hadoop_使用Apache Hadoop计算PageRanks

apache hadoop目前&#xff0c;我正在接受Coursera的培训“ 挖掘海量数据集 ”。 我对MapReduce和Apache Hadoop感兴趣已有一段时间了&#xff0c;通过本课程&#xff0c;我希望对何时以及如何MapReduce可以帮助解决一些现实世界中的业务问题有更多的了解&#xff08;我在这里介…

730阵列卡支持多大硬盘_凯捷月销破2万,配6座头等舱空间,到底有多舒服?试驾了才知道...

能够在还未上市的前一个月&#xff0c;就以预售的方式卖出超过2万台&#xff0c;上汽通用五菱在乘用车市场之中的号召力可见一斑。过去我们都将五菱视为商务领域的铭牌&#xff0c;包括宏光、荣光、之光等等家族&#xff0c;都在各自细分市场占据着最顶端位置。如今&#xff0c…

C语言循环嵌套

在C语言中&#xff0c;if-else、while、do-while、for 都可以相互嵌套。所谓嵌套&#xff08;Nest&#xff09;&#xff0c;就是一条语句里面还有另一条语句&#xff0c;例如 for 里面还有 for&#xff0c;while 里面还有 while&#xff0c;或者 for 里面有 while&#xff0c;w…

rem 前端字体_web前端入门到实战:一次搞懂CSS字体单位:px、em、rem和%

对于绘图和印刷而言&#xff0c;“单位”相当重要&#xff0c;然而在网页排版里&#xff0c;单位也是同样具有重要性&#xff0c;在CSS3普及以来&#xff0c;更支持了一些方便好用的单位&#xff08;px、em、rem…等&#xff09;&#xff0c;这篇文章将整理这些常用的CSS单位&a…

jvmti_JVMTI标记如何影响GC暂停

jvmti这篇文章分析了为什么Plumbr Agents在某些情况下以及如何延长GC暂停的时间。 对基本问题进行故障诊断揭示了有关在GC暂停期间如何处理JVMTI标记的有趣见解。 发现问题 我们的一位客户抱怨说&#xff0c;附加了Plumbr代理后&#xff0c;应用程序的响应速度明显降低。 通过…

C语言-使用goto语句从循环中跳出

实例代码// //实现功能&#xff1a;使用goto语句从循环中跳出 //#include "stdio.h"#define EXIT 0void show_Menu(){printf("菜单选项:\t");printf("1&#xff1a;显示\t");printf("2&#xff1a;添加\t");printf("3&#xff1a…

粒子群算法组卷_粒子群(PSO)算法概念及代码实现

粒子群算法的由来及思想粒子群算法最早是由两名美国的科学家基于群鸟觅食&#xff0c;寻找最佳觅食区域的过程所提出来的&#xff0c;作为一种智能算法&#xff0c;PSO模拟的就是最佳决策的过程&#xff0c;鸟群觅食类似于人类的决策过程&#xff0c;想想在你做出选择之前&…

装饰器模式java_Java 8的装饰器模式

装饰器模式java在最近的一篇文章中&#xff0c;我描述了装饰器模式如何挽救了我的一天。 我给出了一个小代码段&#xff0c;其中包含创建装饰器的最简单方法&#xff0c;但承诺Java 8会有更好的方法。 这里是&#xff1a; 用Java 8装饰 HyperlinkListener listener this::ch…

C语言-反转字符串

实例代码// //实现功能&#xff1a;输入一个字符串&#xff0c;然后将该字符串反向输出 //#include "stdio.h" #include "string.h"#define N 50void convert_str(char str[N]);void convert_str(char str[N]){int j;char temp;for (int i 0; i < strl…

信捷步进指令的使用_步进电机驱动器的模式

步进电动机和步进电动机驱动器构成步进电机驱动系统。步进电动机驱动系统的性能&#xff0c;不但取决于步进电动机自身的性能&#xff0c;也取决于步进电动机驱动器的优劣。对步进电动机驱动器的研究几乎是与步进电动机的研究同步进行的。步进电机驱动器有三种基本的步进电机驱…

jersey客户端_每个客户使用Jersey处理的Cookie

jersey客户端许多REST服务会将cookie用作身份验证/授权方案的一部分。 这是一个问题&#xff0c;因为默认情况下&#xff0c;旧的Jersey客户端将使用单例CookieHandler.getDefault &#xff0c;大多数情况下该值为null&#xff0c;如果不为null&#xff0c;则在多线程服务器环境…

C语言灵魂篇|指针作为函数返回值

C语言允许函数的返回值是一个指针&#xff08;地址&#xff09;&#xff0c;我们将这样的函数称为指针函数。下面的例子定义了一个函数 strlong()&#xff0c;用来返回两个字符串中较长的一个&#xff1a;#include #includechar *strlong(char *str1, char *str2){ if(strlen(s…

css 样式尾部带感叹号是什么意思_CSS书写规范

推荐大家看看百度FEX前端团队和腾讯AlloyTeam前端团队的CSS代码规范。fex-team/styleguide​github.comCode Guide by AlloyTeam​alloyteam.github.io1. 样式属性顺序单个样式规则下的属性在书写时&#xff0c;应按功能进行分组&#xff0c;组之间需要有一个空行。同时要以Pos…