1

我正在开发一个 AJAX 应用程序。用户单击一个按钮,他的名字将保存到数据库中并显示在 <div> 中,其内容是通过 AJAX 长轮询从数据库中获取的。数据库还包含一个表示过期的时间戳:不得接受超过该时间戳的订阅。用户订阅也有限制。

我有一个由 AJAX 请求调用的 PHP 脚本,该脚本查询数据库并检查是否过期(点击的时间戳由 JavaScript 计算并通过 AJAX 发送)。它还检查用户限制:我在用户和产品(订阅)之间有 N 对 N 的关系。这些任务显然需要时间,我担心可能出现的并发问题。我应该使用数据库事务吗?我可以使用什么技术来确保此操作的原子性?

4

1 回答 1

2

这取决于完成那些“长期”任务的工作类型。

一般信息:

如果您只插入用户驱动的数据和在 PHP 中生成的数据,而没有被读取和/或与从数据库中获取的数据交叉关联,那么事务性应该不是问题。

如果您正在更新数据并将其与数据库中的其他元素进行交叉关联,那么您需要开始使用事务并仔细选择您计划使用的事务的隔离级别。

当并发性增加时,事务会严重影响速度。选择一个非常安全的隔离级别可能比您的应用程序所需的更安全,并且您可能会给 MVCC 添加许多不必要的工作。

此外,将事务用作单独的 PHP api 调用并管理应用程序中的回滚逻辑会增加事务的总体持续时间,因为它会增加 PHP 生成的所有处理延迟。如果您可以将 DB 通信压缩为一次通信中请求的一组查询,那就更好了。

案例信息:

让我们考虑这种情况:有 8 个插槽,订阅了 7 个用户。两个用户几乎同时单击订阅按钮。当为最后点击用户启动控制脚本时,可能仍会执行对第一个点击用户订阅的查询。这意味着系统接受两个用户作为有效订阅。

这属于我解释的第二种情况,即您将用户驱动的数据与数据库中的数据进行交叉关联的情况。在提交用户驱动器数据之前,您正在读取数据库的状态,所以是的,在这种情况下您需要事务。

有可能推测一个更新语句的内在原子性。AnyUPDATE table_name SET x = x+1 WHERE a = 'value';保证是原子的。你可以利用它来发挥你的优势。

所有订阅 PHP 线程必须首先减少订阅者计数。如果减量时受影响的行数不为0,说明减量成功,可以继续提交用户相关数据,否则通知用户0.3ms太慢了。

于 2012-07-24T13:44:30.523 回答