数据缓存会造成干扰吗?

时间:2011-02-06 15:04:39

标签: php mysql caching

我正在为我的PHP站点编写一个具有数据缓存功能的新引擎。现在我想知道这些脚本之间是否存在干扰。请考虑以下示例:

假设许多用户访问了与摄影相关的网站,其中两个用户几乎完全同时运行两个脚本。

脚本1从数据库中删除名为“FooBar”的用户及其所有照片。

脚本2显示照片nr 12345(由FooBar制作)。

  1. (脚本1)检查用户'FooBar'是否存在。将其ID存储在变量$id
  2. (脚本2)检查照片是否存在12345。将所有者ID存储在变量$owner
  3. (脚本1)query("DELETE FROM users WHERE id='$id' ");
  4. (脚本2)query("SELECT name FROM users WHERE id='$owner' "); //错误
  5. (脚本1)query("DELETE FROM photos WHERE owner='$id' ");
  6. 正如我们所见,脚本2检测到照片存在,但其所有者已被删除。

    问题是:PHP脚本是否按顺序处理(因此呈现的方案是不可能的)?如果没有,在单个脚本中发送多个查询时,我该怎么做才能防止此类错误?

    非常感谢你。


    感谢您的回答。呈现的场景只是一个例子,我知道这可以以更好的方式完成。因此,在创建大型网站时,我必须时刻意识到可以在运行时更改数据。

    但是这样,我根本无法信任存储在php变量中的任何信息。你如何应对这类问题?在一个查询中更新或获取所有数据?

2 个答案:

答案 0 :(得分:1)

所呈现的场景是可能的。我唯一能说你能做的就是为这种可能性编写一个错误:正如你所示,查询4没有返回有效的所有者。现在你可以做几件事,其中只是一些例子:

  • 在合并查询中返回所有者名称,以便在找到图片所有者时至少显示名称(在第2点)。如果以后你想要展示更多,你只需返回主人不再感谢(不再)。这就是发生了什么(它在负载之间被删除),所以即使对用户来说有点奇怪,他也必须处理它:)
  • 只需在第4点显示错误,有点像上一个示例的第二部分。你很快就得到了一个结果,但随后就消失了。所以你返回“无法加载用户”或类似的东西。

答案 1 :(得分:1)

确实,竞争条件是可能的。

我会说在删除脚本中删除用户 他的照片之前,我觉得很奇怪。如果在删除用户之后但在删除照片之前出现了某些内容,那么数据库仍会显示他的孤立照片。通常,事务(使用支持它们的存储引擎,如InnoDB)可以缓解此问题。

至于竞争条件本身,我认为有些技术使用行锁定来阻止其他进程同时访问它们。

[如果我有机会做一些研究,我会填写更多细节。到目前为止,我对'mysql row locking'的简短研究表明,某些引擎实际上隐式锁定了受事务影响的任何行。但我承认在那里没有直接经验。]