hibernate jpa_JPA / Hibernate:基于版本的乐观并发控制

hibernate jpa

本文是对Hibernate和JPA中基于版本的乐观并发控制的介绍。 这个概念已经很老了,上面已经写了很多东西,但是无论如何我都看到了它被重新发明,误解和滥用。 我在写它只是为了传播知识,并希望引起对并发控制和锁定的兴趣。

用例

假设我们有一个供多个用户使用的系统,其中每个实体可以由多个用户修改。 我们要防止两个人加载一些信息,根据他们看到的内容做出一些决定并同时更新状态的情况。 我们不希望丢失在第一个事务中首先单击“保存”的用户所做的更改,而这些更改会在随后的事务中被覆盖。

它也可能在服务器环境中发生–多个事务可以修改共享实体,我们希望防止出现以下情况:

  1. 交易1载入资料
  2. 事务2更新该数据并提交
  3. 使用在步骤1中加载的状态(不再是当前状态),事务1执行一些计算并更新状态

在某些方面,它与不可重复的读取具有可比性。

解决方案:版本控制

因此,Hibernate和JPA实现了基于版本的并发控制的概念。 运作方式如下。

您可以使用@Version<version> (数字或时间戳)标记一个简单的属性。 这将是数据库中的特殊列。 我们的映射如下所示:

@Entity
@Table(name = 'orders')
public class Order {@Idprivate long id;@Versionprivate int version;private String description;private String status;// ... mutators
}

当这样的实体持续存在时,version属性将设置为起始值。

每当更新时,Hibernate都会执行如下查询:

update orders
set description=?, status=?, version=?
where id=? and version=?

请注意,在最后一行, WHERE子句现在包括version 。 此值始终设置为“旧”值,以便仅在具有预期版本时才更新行。

假设有两个用户在版本1中加载订单,并花一些时间在GUI中查看订单。

安妮决定批准该订单并执行该操作。 数据库中的状态已更新,一切正常。 传递给update语句的版本如下:

update orders
set description=?, status=?, version=2
where id=? and version=1

如您所见,在持久化更新持久层时,版本计数器将增加到2。

在她的GUI中,Betty仍然具有旧版本(编号1)。 当她决定对订单执行更新时,该语句如下所示:

update orders
set description=?, status=?, version=2
where id=? and version=1

此时,在Anne进行更新之后,数据库中该行的版本为2。因此,第二次更新影响0行(没有与WHERE子句匹配的行)。 Hibernate会检测到该错误,并检测到org.hibernate.StaleObjectStateException (包装在javax.persistence.OptimisticLockException )。

结果,第二个用户除非刷新视图,否则无法执行任何更新。 为了获得适当的用户体验,我们需要进行一些干净的异常处理,但是我将省略。

组态

在这里自定义的内容很少。 @Version属性可以是数字或时间戳。 数字是人为的,但通常在内存和数据库中占用较少的字节。 时间戳较大,但始终会更新为“当前时间戳”,因此您可以实际使用它来确定实体的更新时间。

为什么?

那为什么要使用它呢?

  • 它提供了一种方便且自动化的方式来保持上述情况下的一致性。 这意味着每个动作只能执行一次,并保证用户或服务器进程在制定业务决策时看到最新状态。
  • 设置只需很少的工作。
  • 由于其乐观的性质,因此速度很快。 在任何地方都没有锁定,只有一个字段添加到同一查询中。
  • 在某种程度上,即使在已提交读事务隔离级别的情况下,它也可以确保可重复读。 它将以异常结束,但是至少不可能创建不一致的状态。
  • 它适用于很长的对话,包括跨越多个事务的对话。
  • 在ACID数据库上的所有可能方案和竞争条件下,它都是完全一致的。 更新必须是顺序更新,更新涉及行锁定,而“第二”更新将始终影响0行并失败。


演示版

为了演示这一点,我创建了一个非常简单的Web应用程序。 它将Spring和Hibernate连接在一起(在JPA API后面),但是它也可以在其他设置中工作:Pure Hibernate(没有JPA),具有不同实现的JPA,非webapp,非Spring等。

该应用程序保留一个具有与上述类似的架构的Order ,并以Web表单显示该Order ,您可以在其中更新描述和状态。 要尝试并发控制,请在两个选项卡中打开页面,进行不同的修改并保存。 如果没有@Version请尝试相同的@Version

它使用嵌入式数据库,因此需要最少的设置(仅Web容器),并且只需重新启动即可从新数据库开始。

这非常简单-在@Transactional @Controller访问EntityManager并直接使用JPA映射的实体支持表单。 对于不太琐碎的项目而言,这可能不是最好的处理方法,但至少它将所有代码都集中在一个位置,并且非常容易掌握。

可以在我的GitHub存储库中找到Eclipse项目的完整源代码。

参考: 在我们的JCG合作伙伴 Konrad Garus的Squirrel博客上,JPA / Hibernate中基于版本的乐观并发控制 。

翻译自: https://www.javacodegeeks.com/2012/11/jpahibernate-version-based-optimistic-concurrency-control.html

hibernate jpa

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

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

相关文章

X86汇编快速入门

本文翻译自&#xff1a;http://www.cs.virginia.edu/~evans/cs216/guides/x86.html 本文描述基本的32位X86汇编语言的一个子集&#xff0c;其中涉及汇编语言的最核心部分&#xff0c;包括寄存器结构&#xff0c;数据表示&#xff0c;基本的操作指令&#xff08;包括数据传送指令…

Django(三)框架之第二篇

https://www.cnblogs.com/haiyan123/p/7717788.html 一、知识点回顾 1、MTV模型 model&#xff1a;模型&#xff0c;和数据库相关的 template&#xff1a;模板&#xff0c;存放html文件&#xff0c;模板语法&#xff08;目的是将变量如何巧妙的嵌入到HTML页面中&#xff09;。 …

使用GDB调试C库

用gdb调试程序时&#xff0c;一般的函数都可以step进去&#xff0c;可是C库函数却直接跳过了。 网上找了些资料&#xff0c;记录一下&#xff01; 1.安装C库的debug版本 [plain] view plaincopy print?sudo apt-get install libc6-dbg 安装完后&#xff0c;在/usr/lib目录下…

matlab imfilter对图像进行滤波

功能&#xff1a;对任意类型数组或多维图像进行滤波。 用法&#xff1a;B imfilter(A,H)    B imfilter(A,H,option1,option2,...)    或写作g imfilter(f, w, filtering_mode, boundary_options, size_options) 其中&#xff0c;f为输入图像&#xff0c;w为滤波掩模&…

MapStruct:将数据从一个bean传输到另一个bean

将数据从一种形式转换为另一种形式在IT行业中是一种被高度利用的概念。 MapStruct通过在编译时生成映射器实现&#xff0c;允许基于注释的Bean转换。 这样可以确保在运行时没有性能开销。 什么是MapStruct&#xff1f; MapStruct是一个代码生成器&#xff0c;它基于约定优于配…

eclipse发布rest_在Eclipse中高效运行HTTP / REST集成测试

eclipse发布rest最近&#xff0c;我有机会使用由我亲爱的Holger Staudacher编写的OSGi-JAX-RS-Connector库。 通过连接器&#xff0c;您可以通过将Path注释的类型注册为OSGi服务来轻松发布资源-实际上&#xff0c;它工作得很好。 对我来说&#xff0c;使用普通的JUnit测试编写…

gdb调试命令

本文主要参考自&#xff1a;http://www.cnblogs.com/zzx1045917067/archive/2012/12/26/2834310.html&#xff0c;进行了一点补充和编排&#xff1b;Core dump部分参考了&#xff1a;http://blog.ddup.us/?p176。 gdb是一个在UNIX环境下的命令行调试工具。 如果需要使用gdb调试…

分享一个windows下检测硬件信息的bat脚本

文件名必须以.bat结尾&#xff0c;如果出现闪退&#xff0c;请右击鼠标&#xff0c;以管理身份运行即可 echo offcolor 0atitle 硬件检测 mode con cols90sc config winmgmt start auto >nul 2<&1net start winmgmt 2>1nulsetlocal ENABLEDELAYEDEXPANSIONecho 主…

matlab imfinfo返回图像信息

语法&#xff1a; info imfinfo(filename,fmt) %输入图像名&#xff0c;图像的格式 info imfinfo(filename)%输入图像名 示例程序&#xff1a; info imfinfo(C:\test1.jpg) %返回图像信息&#xff0c;注意&#xff1a;输入必须字符串 info.Width …

Apache Camel 2.18发布–包含内容

本周发布了Apache Camel 2.18.0 。 此版本是重要版本&#xff0c;我将在此博客文章中重点介绍。 Java 8 Camel 2.18是要求Java 1.8的第一个发行版&#xff08;例如&#xff0c;容易记住的Camel 2.18 Java1.8。Camel2.17 Java 1.7&#xff09;。 我们采取了谨慎的方法&…

C# 中 FindControl 方法及使用

FindControl 的使用方法 FindControl (String id)&#xff1a; 在页命名容器中搜索带指定标识符的服务器控件。&#xff08;有点类似javascript中的getElementById(string)&#xff09; 今天做了一个打印的报表 &#xff0c;要求在指定位置显示列表中某字段的内容&#xff0c;…

matlab imresize对图像进行缩小放大

matlab中函数imresize简介&#xff1a; 函数功能&#xff1a;该函数用于对图像做缩放处理。 调用格式&#xff1a; B imresize(A, m) 返回的图像B的长宽是图像A的长宽的m倍&#xff0c;即缩放图像。 m大于1&#xff0c; 则放大图像&#xff1b; m小于1&#xff0c; 缩小图像。…

matlab imrotate图像旋转

B imrotate(A,angle) 将图像A&#xff08;图像的数据矩阵&#xff0c;既可以是灰度图像&#xff0c;也可以是RGB图像&#xff09;绕图像的中心点旋转angle度&#xff0c; 正数表示逆时针旋转&#xff0c; 负数表示顺时针旋转。返回旋转后的图像矩阵。 B imrotate(A,angle,met…

理解爬虫原理

1.简单说明爬虫原理 爬虫就是通过互联网各个沾点组成的节点网&#xff0c;通过代码返回给浏览器&#xff0c;然后解析这部分的代内容&#xff0c;将网页内的内容简洁地呈现在我们的面前。爬虫的流程可以分为&#xff1a;发送请求、获取响应内容、解析内容、保存数据。 2.使用 r…

带有Java DSL的Spring Integration MongoDB适配器

1引言 这篇文章解释了如何使用Spring Integration从MongoDB数据库中保存和检索实体。 为了实现这一点&#xff0c;我们将使用Java DSL配置扩展来配置入站和出站MongoDB通道适配器。 例如&#xff0c;我们将构建一个应用程序&#xff0c;使您可以将订单写入MongoDB存储&#xff…

matlab linspace

用法&#xff1a;linspace(x1,x2,N)   功能&#xff1a;linspace是Matlab中的一个指令&#xff0c;用于产生x1,x2之间的N点行矢量。其中x1、x2、N分别为起始值、中止值、元素个数。若缺省N&#xff0c;默认点数为100。在matlab的命令窗口下输入help linspace或者doc linspac…

Linux strace命令

简介 strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界&#xff0c;进程不能直接访问硬件设备&#xff0c;当进程需要访问硬件设备(比如读取磁盘文件&#xff0c;接收网络数据等等)时&#xff0c;必须由用户态模式切换至内核态模式&#xff0c;通 过系统调用…

网站发布

1.文件发布 右击工程&#xff0c;选择发布 发布方法选择文件发布&#xff0c;打开你的程式路径&#xff0c;然后一步步操作即可。 转载于:https://www.cnblogs.com/alannxu/p/10613453.html

什么是javax.ws.rs.core.context? [第4部分]

如何使用Context批注 在什么是javax.ws.rs.core.context的第3部分中&#xff1f; 您学习了如何在请求和配置&#xff0c;提供程序和应用程序实例中使用Context批注。 在本文中&#xff0c;您将学习如何使用Context批注注入HttpServletResponse和HttpServletRequest类。 获取对…

matlab im2double

im2double函数&#xff0c;如果输入是 uint8 unit16 或者是二值的logical类型&#xff0c;则函数im2double 将其值归一化到0&#xff5e;1之间。