网站用ai做还是ps,研发流程的六个阶段,vps挂网站,合肥网络推广公司哪家专业本文是Hibernate和JPA中基于版本的乐观并发控制的简介。 这个概念已经很老了#xff0c;上面已经写了很多东西#xff0c;但是无论如何我都看到了它被重新发明#xff0c;误解和滥用。 我在编写它只是为了传播知识#xff0c;并希望引起人们对并发控制和锁定的兴趣。 用例… 本文是Hibernate和JPA中基于版本的乐观并发控制的简介。 这个概念已经很老了上面已经写了很多东西但是无论如何我都看到了它被重新发明误解和滥用。 我在编写它只是为了传播知识并希望引起人们对并发控制和锁定的兴趣。 用例 假设我们有一个供多个用户使用的系统其中每个实体可以由多个用户修改。 我们希望避免两个人加载一些信息根据他们看到的内容做出一些决定并同时更新状态的情况。 我们不希望丢失在第一个交易中首先单击“保存”的用户通过覆盖它们所做的更改。 它也可能在服务器环境中发生–多个事务可以修改共享实体我们希望避免出现以下情况 交易1载入资料 事务2更新该数据并提交 使用在步骤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?, version2
where id? and version1 如您所见在持久化更新持久层时版本计数器将增加到2。 在她的GUI中Betty仍然具有旧版本编号1。 当她决定对订单执行更新时该语句如下所示 update orders
set description?, status?, version2
where id? and version1 此时在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