【问题标题】:Concurrency control in web applicationWeb 应用程序中的并发控制
【发布时间】:2014-12-27 21:55:32
【问题描述】:

我必须解决这种情况:在我的 Spring + JPA Web 应用程序中,我有一个类似于 excel 工作表的 jsp。

所以我有一定数量的单元格,每个单元格都保存在带有附加信息的数据库表中:每个单元格都有一行。

id | value | column | row | ...

我使用这种结构是因为我的 jsp 表中的列数是动态的。

目前,当我保存单元格时我会截断数据库表中的当前行集并重新插入所有新行。这是我发现更新大量行的最快方法。

但是现在我有一个并发问题:jsp页面可以被不同的用户同时使用,这会导致覆盖其他用户节省的问题

我需要在我的网络应用中实现某种锁定。我发现主要有两种类型的锁:乐观与悲观。

您能建议我解决这种情况的常用方法吗?我需要在数据访问级别还是服务级别实施锁定?

注意更清楚一点:表值在用户之间共享,但可以由授权用户之间的任何人更新。

【问题讨论】:

  • 我在你的问题中缺少的词是:transaction
  • @zapl 是的,我在我的应用程序服务中使用事务,但是如何使用事务来解决我的问题?
  • 这在很大程度上取决于您的用户是否会经常进行小改动或很少进行大改动。如果经常小,那么您可以检查数据是否被修改并拒绝更改(它已丢失)。使用 large seldom,您最好在用户开始修改网格时立即锁定所有内容。在修改完成之前,您可以允许其他用户进行只读访问。
  • 你想锁定什么?单个值(乐观锁定不适用于您当前的截断/创建方法)或某些更高级别的实体,即作为一个整体的行集。 stackoverflow.com/questions/19454003/…

标签: java spring spring-mvc jpa concurrency


【解决方案1】:

解决方案可能取决于行为要求。

以下场景如何:用户 A 和 B 开始更改一些值,然后用户 A 按下保存按钮并保存数据,之后用户 B 也这样做了。用户 B 收到一条错误消息,内容类似于“数据已更新,请重新加载页面”。他重新加载页面并丢失了他所做的所有更改:(只有在那之后他才能保存他的更改,但他必须再做一次。

其他可能的情况:用户 A 和 B 访问页面,但只有第一个用户可以保存他的工作,其他用户会看到类似“其他人正在编辑页面,稍后再试”的消息”。

对于第一种情况,您可以实现以下内容:表的每一行(在数据库中)都有一个 last-update-timestamp,每次更改此行时都会更新为当前时间。 现在,让我们假设用户 A 在打开页面时获取时间戳为 1 的行,用户 B 稍微慢了一点,并获得了时间戳为 2 的同一行。但是,他更快地进行了更改,并首先按下了保存按钮。现在,该行以时间戳保存在数据库中,比如说5。用户 A 正在尝试保存他的更改,但他的数据的时间戳是 1,这与 DB 中当前的 5 不同。这意味着有人已经更改了该数据,他应该会看到我上面提到的错误消息。

第二种情况更难实现。我认为最好的方法是向 DB 打开事务

  • 读取我们想要的行;
  • 为所有这些人添加一些“锁定”之类的标志到true
  • 如果某行已被锁定,则失败(或返回可用行,具体取决于您的需要)。但是,可能应该失败;
  • 返回行到jsp页面;

现在,如果其他用户请求相同的行,事务将失败,他将无法开始更改数据。

用户 A 在保存数据时应将这些locked 标志放回false重要的事情:这些锁应该有超时,以防止用户打开页面并关闭它而不保存的情况(或浏览器崩溃,或其他)。您可能还想为同一个用户实现某种锁定 reackquire - 当用户第一次打开页面时,然后关闭它而不保存数据并再次打开 - 他应该能够编辑数据。这可以通过以某种方式识别用户来完成 - 登录、cookie 等等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-14
    • 2012-11-06
    • 2010-11-24
    • 2018-08-18
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多