PHP + mySQL 和并发数据库访问问题

PHP + mySQL and concurrent database access issues

我正在寻求有关如何解决使用 PHP 和 mySQL 构建的 Web 应用程序中的并发访问问题的建议。

应用程序用户自定义我称之为“collection”的东西。定制完成后,他们可以单击 PayPal“立即购买”按钮并购买 collection.

collection 由两组独立的事物组成:一组小部件和一组小工具。 “自定义”涉及选择哪些小工具要包含在小工具组中,哪些小工具要包含在小工具组中。

这是一种简化的伪实体关系图:

有大量 运行 小部件和小工具可供选择,但每个小部件和小工具都是独一无二的,一次只能在一个组中使用。

购买 collection 时出现问题。我需要确保当用户单击“立即购买”按钮时,他们为其小工具组选择的小工具,以及他们为小工具组选择的小工具尚未在另一个 paid-for collection.

想象一下两个人同时使用该系统。每个人都创建了一个 collection* 包含一些相同的小部件 and/or 小工具,然后进入结帐页面,在那里他们都在同一时刻点击了“立即购买”按钮。 运行 测试所选 widgets/gadgets 是否已被使用的标准查询在这种情况下是不可靠的,因为对于两个用户,系统都会回复“这些可用”,并且每个用户都可以购买他们的 collection 拥有“double-booked 资源”(可以说是)。

所以我今天阅读了很多有关 t运行saction 和锁定的资料。我认为这必须包含在我的解决方案中,但我很难想象它是如何工作的。

此刻我所能想到的是这样的:在点击“立即购买”按钮时,我开始一个 t运行 操作,然后 运行 一个查询来锁定(到防止其他 session 读取 写入)小部件 table 中的所有行,以及小工具 table 中列出的每个项目的所有行collection。随着 t运行saction 启动和那些锁定到位,我可以 运行 查询来测试是否有任何选定的项目已经在使用中。 如果查询表明这些物品未使用,我将允许继续购买,一旦完成我将释放锁。

如果查询表明项目已被使用,我会 return 出错并释放锁。

如果另一个用户试图同时购买包含一些相同 widgets/gadgets 的 collection,他们要么会收到锁定超时,而我会 return 一个错误;或者他们必须等到另一个 session 移除了它的锁,然后 - 当他们的 session 应用相同的锁和 运行 相同的查询时 - 他们会看到“已在使用”错误。

所以我有两个问题。这听起来像是处理我的情况的最佳方式吗?其次,如果是的话,是不是像我描述的那样do-able?

非常感谢您

*可能留着以后用。我允许用户创建包含他们喜欢的任何 widgets/gadgets 的 collections - 即使是已经在使用的那些 - 推理如果他们现在推迟购买,那么当他们稍后继续购买时,这些资源可能再次可用

是的,是的。是的,这是最好的方法,因为它是最明显和最常用的。是的,这种方法行得通,我自己使用过它,并且处理过其他人使用它编写的代码。

尽量不要在持有交易的同时进行分析;预测试,开始事务,设置乐观锁,结束事务,查看哪些成功了,如果有的已经加锁,则释放刚才设置的锁。您的数据库将感谢您。