当前位置: 首页 > 知识库问答 >
问题:

最佳实践Hibernate乐观锁定和web应用程序

凌运恒
2023-03-14

我有一个用Tapestry5(javawebframework)和Hibernate制作的web应用程序。现在我尝试添加乐观锁定。所以我添加了一个版本属性,乐观的锁定可以工作,所以这很容易,很快。

但是,由于我的web应用程序使用“每个请求一个会话”模式,我不确定利用这种乐观锁定的最佳方式是什么。

发生了什么:

用户 A 打开包含表单的页面,该表单加载了来自实体 A(版本 1)的值。

UserB打开带有表单的页面,该表单加载了entityA(版本1)中的值。

用户 A 更改了一些值并提交表单。-

UserB更改一些值并提交表单-

应该发生什么

不应提交对UserB的更改。但是,由于每请求会话模式,Hibernate的乐观锁定错误可能发生的时间窗口被缩短为从提交后的新请求到提交的时间间隔,这不是预期的结果。

可能的解决方案

经过一些研究,我发现如下:

    < li >将隐藏字段添加到实体版本的表单中

我可以使用此值在提交前设置实体的版本,但HiberNate留档不建议设置此值。此外,它仅在实体被分离并重新附加时才有效,因为HiberNate会忽略手动设置的版本值。

其次,我可以使用此版本值手动检查呈现表单时的版本是否与提交时请求中加载的实体的版本相同。然后,如果需要,自己会抛出一个乐观锁定异常

  • 将分离的实体放入 HttpSession 中,这样我就不必在提交时再次加载它

结论

这些方法有效,但对我来说似乎不太实用,而且很容易出错。所以我想知道其他人是如何实现这个问题的。

共有2个答案

段超
2023-03-14

当您分离持久实体以将其传输到web层时,例如,创建DTO以将对象传输到web层。在这种情况下,我们将使用getter和setter将实体对象转换为DTO对象。

如果需要用乐观锁维护并发控制,就要在应用程序中维护版本号(和手动设置版本号不同)。否则,我们无法指示hibernate加载的记录的旧版本是什么。在hibernate文档中,它说“保持断开的会话靠近持久层。使用EJB有状态会话html" target="_blank">bean在三层环境中保持会话。不要将其传输到web层,甚至不要将其序列化到单独的层,而是将其存储在HttpSession中。,但是所有的环境在业务层都没有EJB有状态会话beans。在这种情况下,我们必须维护版本号。

只要你能维护版本,你就不需要在程序中手动检查版本,如果你让Hibernate来做这件事是有效的,因为你不能预测你的对象层次结构的深度。

所以你能做的是,如果你在web层使用分离的对象,你必须再次设置持久实体的版本,然后hibernate会处理并发控制。

锺离声
2023-03-14

我最终实现了以下内容:

  • 向具有实体版本的窗体添加隐藏字段
  • 表单 dto 对象的使用
  • 将这些 dto 对象附加到 httpsession(跨多个请求的会话状态)
  • DTO和实际对象之间的手动版本检查
 类似资料:
  • 所以我有一个Web应用程序,其中前端是用React编写的,后端是用NodeJs/NestJ编写的,并且处于部署应用程序的阶段。我有一个运行Ubuntu的Linode服务器,我最初的想法是安装Docker 那么,这是设置应用程序的好方法吗?这种设置有什么利弊吗?除了因为需要服务器数量而定价之外?或者还有其他更有益的选择吗? 提前致谢。

  • 问题内容: 我试图按顺序实施乐观锁定,以避免丢失更新情况。在我的应用程序中,当两个用户获取相同的记录,而第一个用户通过一些更改对其进行更新时。查看相同记录的第二个用户看不到此更改,并且他自己进行了一些更改并更新了该记录。因此,第一人称更改丢失。为了防止这种情况,我写了以下内容,但问题仍然存在。我是这个概念的新手,无法发现问题。 我试图通过阅读doc 11.3.4 来实现这一目标。自定义自动版本控制

  • 我有一个带有和的微服务。我使用注释对中的表执行操作。我遇到的问题是保存操作花费了太多的时间,所以我希望读取操作不被它阻塞。注意,保存是通过持久化实体来执行的。 当前,在所有并发保存操作完成之前,所有读取操作都不会返回结果,这意味着表被锁定。相反,我希望实现乐观锁定。我怎样才能做到呢?

  • 我正在构建一个全栈 Web 应用程序。我正在使用 Vue.js作为前端,Spring启动用于后端,将 PostgreSQL docker 容器用于数据库。但是,我很好奇,一旦我完成了Web应用程序的开发,我应该在哪里以及如何部署它。 我在下面列出了我的问题: < li >我应该在哪里部署我的全栈应用程序,如AWS、GCP、Hiroku或任何其他平台。 < li >部署我的前端、后端和数据库的最佳实

  • 问题内容: 在工作中,我们正在开发一个RESTful应用程序,其中的数据层将由Hibernate处理。但是我们不确定如何处理实体的更新。 我们计划执行以下操作: 1)客户端通过id请求一个实体 2)Hibernate加载该实体,将请求的字段(始终带有版本)复制到DTO,该DTO转换为JSON并发送给客户端 3)客户端管理一些字段并发送实体(版本号)返回到服务器。 4)服务器接收转换为DTO的JSO

  • 我们有一个系统,我们偶尔会得到一个乐观的锁定异常。我们在代码中已经解决了这个问题,但现在我正在查看JPA 2,并看到它有一个用于处理这个问题的注释(@版本) 我们的问题是,一个表上有多个事务,如果表锁已满,则即使未对相同的记录进行更改,也会导致乐观锁定异常。 我们在JBoss 4.2服务器上使用hibernate,数据库可以是MySQL或SQL服务器。 如果改为使用@Version,这会在两个数据