锁定访问者,直到mysql查询完成

时间:2010-09-26 09:40:24

标签: php mysql lamp

我在网站上有一堆页面,可以在一个页面上执行的操作取决于网站访问者的数据库中的信息。所以,假设访问者A来到页面B并更新数据库以显示他们已加入某个组。然后访问者转到页面C,组页面。如果用户是组成员,则会显示成员内容。如果不是,则会显示非会员内容。问题出现了(顺便说一句,页面是在php中):

在理想的世界中,页面B上运行的查询将在用户转到页面C之前立即完成,因此数据库始终填充有关成员资格状态的最新信息。但是,可能会发生服务器负载很大,并且在用户转到页面C时查询未完成。因此,即使用户是该组的成员,也不会在页面C上反映出来。因为查询尚未完成。

有没有办法让它成为如果用户在页面上运行查询,直到该查询完成他们尝试访问的任何其他页面将只是“挂起”并在查询完成后加载,或直到给定时间已经过去了?我可以手动制作这个系统,但是如果mysql和php已经内置了一些东西,那就更好了。

如果重要,我正在使用LAMP服务器。

3 个答案:

答案 0 :(得分:1)

除非您做任何像复制数据库服务器或消息队列系统那样的事情,否则这实际上是单个MySQL服务器和PHP的工作方式。在页面B上发出UPDATE或INSERT,查询将不会返回,直到它被提交。因此,在完成查询之前不要从页面B返回任何HTML - 无论如何你都不想这样做,因为你要确保首先没有错误。然后页面C就可以了。

答案 1 :(得分:0)

假设您有一个唯一标识当前用户的字符串,例如'identifyuser',请选择合理的超时并在给定请求的任何其他数据库活动之前执行SELECT GET_LOCK('identifyuser',timeout),并在SELECT RELEASE_LOCK('identifyuser')之后执行{{3}}请求的所有数据库活动。

答案 2 :(得分:0)

在B页进行确认之前,访问者是否只是不能显示指向页面C的链接?所以他们加入了B页的小组,这是通过向一个单独的中间形式处理器页面F提交一个表单帖子,然后一旦完成(即mysql插入成功完成),它再次加载页面B,并提供适当的新信息和指示第C页。

如果必须始终显示页面C链接,或者用户可以将其加入书签,那么页面C也可以显示记录的日期,为用户提供“刷新”按钮,以防他的记录与他只是想告诉他等一下再试一次。

在任何情况下,在mysql中你都在谈论概念或行锁定,但是你试图将它应用于多入口站点。我不知道PHP中有任何这样的内置机制,但如果您愿意,可以使用每个用户的信号量伪造它:

  • 用户启动操作
  • PHP通过创建唯一文件或在内存存储区(如memcache)或用户会话中设置唯一键来为该用户设置锁定
  • 该锁定表示该操作尚未完成
  • PHP执行操作(mysql插入,无论如何)
  • 一旦操作完成并经过验证,请删除锁定

然后你可以使用锁的存在来确定页面C应该加载并显示描述给用户的内容,例如我上面提到的刷新按钮。