【问题标题】:how to prevent two user edit same content at same time如何防止两个用户同时编辑相同的内容
【发布时间】:2014-09-12 09:43:01
【问题描述】:

我制作了多用户应用程序,其中如果两个用户打开同一个编辑页面并且同时两个用户都在表单中输入数据会有冲突数据,所以我需要一个解决方案,比如如果一个用户打开特定的编辑页面然后所有其他用户屏蔽一段时间并提示他们消息,例如“其他用户编辑同一页面....”

【问题讨论】:

  • 他们编辑 PHP 端的东西(文件?),或者页面本身的内容?
  • 例如:如果用户点击编辑,page_edit 之类的列应该得到 1 而不是 0。当用户完成编辑时,将 1 abck 归零。
  • 编辑页面时,将该页面的数据存储在变量中。当您要保存时,只需查询数据库,如果数据已经更改。如果是这样,它应该显示如下警告:此页面已被其他人编辑。

标签: php jquery codeigniter


【解决方案1】:

也许,

您可以在数据库中添加两列“打开”和“时间”

如果有人正在编辑它,请将“打开”设置为“真”或“假”。 还要为“时间”列设置时间戳。编辑时每隔几秒更换一次时间戳。

如果其他人打开它,请检查“打开”列,如果它是“真”,则计算从“时间”列传递的时间。 如果超过一定时间(例如 2 或 3 分钟),则假设其他用户不再进行编辑并允许该用户进行编辑。

为了清楚起见,

选项 1:

  • 用户点击编辑
  • 检查“open”列,如果为“false”,将其设置为“true”并将时间戳添加到“time”
  • 只要用户在输入字段中输入,每隔 10 秒左右,就会进行一次 AJAX 调用以使用当前时间戳更新“时间”列
  • 用户点击“保存”,“打开”列设置为“假”。 -

选项 2:

  • 用户点击编辑
  • 检查“打开”列,如果为“真”,请检查“时间”列。
  • 如果与当前时间戳的差异超过 2 到 3 分钟,则允许对此用户进行编辑并更新时间戳。

【讨论】:

  • @JaMaBing 更新了我的答案
  • 通过您的编辑,您仍然需要花费一些任意时间。假设我打开编辑,我正在写一个很长的字符串,5 分钟过去了,我还在打字,为什么文件要更改为“关闭”?
  • @Patrick 当文本框中有操作时,它会通过 AJAX 调用每隔 10 秒左右用当前时间戳更新“时间”列。
  • Ajax 是这个问题(或 websockets)的真正答案,但您没有在答案中说明。至少在我看来。
  • 这基本上是我发布的答案,我会删除选项 2,这不是一个真正的选项。但 ajax/websocket 方式是唯一的出路
【解决方案2】:

最好和最简单的方法是在点击编辑后在网站和编辑用户之间保持实时连接。

所以基本步骤:

1) 用户点击编辑。
2) 与该用户启动 ajax 或 websocket 连接,以告诉服务器文件仍在编辑中
3)如果用户手动关闭或只是离开网站,有一些逻辑来处理它的服务器端
4)利润。

对服务器的连续 ajax 调用(如聊天应用程序)可以更新“time_last_edited”列,如果该列超过 10 秒,则文件可以安全编辑,否则意味着有人仍在编辑它。

【讨论】:

    【解决方案3】:

    给内容一个修改时间。在提交新内容之前,请检查时间是否与之前相同。如果不同,则内容已更改,应通知用户。

    绕过大多数边缘情况。

    【讨论】:

    • 问题是,如果你打开一个文件进行编辑,离开电脑5分钟,这个文件仍然为你打开,我也可以打开,导致两个人编辑同一个文件
    • 这一切都取决于您对用户的关心程度。保持不变的是您的系统完整性。
    • 如果我希望防止用户浪费时间编辑已经在其他地方打开的文件,这也是一个 UX 的问题:)
    • 您可以在之后使用差异工具,允许用户合并他们的更改。那里有一些 PHP 实现。
    • 假设这就是你想要的。不完全是OP所要求的。当然你可以运行一个类似 git 的版本跟踪器,但这并不能解决 OP 问题。
    【解决方案4】:

    在表中有一个字段,例如 Page_status 并在用户打开它进行编辑时将其设置为锁定。如果编辑完成,则将其设置为解锁。并且每次在允许每个用户编辑之前检查状态。

    如果用户没有编辑就关闭了页面。然后为每个用户设置会话并设置时间限制,如果会话过期,则将状态设置为解锁。

    【讨论】:

    • 因此您还需要跟踪哪个用户编辑了文件,这样您就可以检查该特定用户的会话是否已过期,您还必须将会话存储在数据库中以检查是否过期。
    【解决方案5】:

    为此,您必须在表中保留标志,如果假设您的表名“userdetails”包含名称、手机、电子邮件、地址等列,那么现在您要再添加两个列名

    使用数据类型 TINYINT,默认值为 0 inuseddatetime,数据类型为 datetime,默认值为 NULL

    因此,只要特定用户打开详细信息进行编辑 将 inused 列更新为 1 和 inuseddatetime 列与当前日期和时间

    因此,当其他用户打开相同的详细信息进行编辑时,如果该列的值为 1,则向他们显示提示。

    为了再次将 1 变为 0, 当第一个用户再次单击提交按钮时更新 inused 列为 0 并且 inuseddatetime 列为空

    在某些情况下,如果用户没有按下提交按钮并离开页面,为了避免这种情况,您可以在服务器上编写 cron 作业,该作业将检查 inuseddatetime 列并将 inused 列更新为 0 列,这是从最后 10 分钟开始的理想列或5分钟

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多