首页 > 解决方案 > 如何在 MVC 应用程序中使用 @Version 注释?

问题描述

我一直在寻找方法来防止两个用户认为他们同时成功地修改了相同的数据。例如,如果两个用户加载了一个编辑页面,并且两个用户都在编辑页面上工作了几分钟,如果用户 A 提交表单以保存,然后用户 B 提交表单,则用户 B 中的表单中的数据将获胜,因为它已更新最后在数据库中。这里的问题是,当用户 A 的工作现在丢失时,两个用户都认为他们的工作被保存而没有任何问题。

我希望我可以使用 JPA @Version注释。我会通过在加载编辑页面时跟踪版本并在提交表单时将该版本发送到后端来做到这一点。来自前端的版本将被放入加载实体的版本字段以进行更新,然后如果版本与数据库中的内容不匹配,我们将依靠 JPA 来阻止保存。在上述情况下,用户 A 将获胜,而用户 B 将收到一条消息,说他们的保存失败,因为数据已被另一个用户更新。

这里的问题是,我现在已经在几个地方读到,在与注释关联的字段中设置的值@Version不应手动编辑。问题是:这只是正常使用的建议,但我的方法实际上会起作用,还是这是更基本的东西,还有其他原因不手动设置版本字段?

我们的堆栈是 Angular 前端/Spring+JPA (Hibernate) 后端,所以请记住,从前端到后端的所有数据交换都是通过 REST 进行的,我们正在将 Java 对象转换为/来自 JSON。所以,我们典型的编辑/保存往返看起来像这样:

  1. 浏览器请求按 ID 编辑实体
  2. 后端获取请求,使用 JPA 查找实体,将实体转换为 JSON,发送到前端作为响应。
  3. 浏览器从响应中获取 JSON,转换为对象,使用正在编辑的对象中的数据绘制和预填充表单。
  4. 用户进行编辑并提交表单。浏览器向后端发送新请求,其中 JSON 表示修改后的实体。
  5. 后端使用 JPA 查找实体,修改它,并使用 JPA 保存它。

需要明确的是,在第 5 步中,如果我们使用@Version注释而不手动设置它,则版本不会更改,并且我们仍然存在一个问题,即一个用户提交表单可能会覆盖另一个用户的更改。我建议前端跟踪版本号,通过编辑将其发送回后端,并让后端在步骤 5 中设置检索到的对象的版本号。如果发生这种情况,不会t 无意中覆盖了前一个用户的保存失败?

标签: javajpaversion

解决方案


推荐阅读