【发布时间】:2012-10-09 21:55:06
【问题描述】:
首先介绍一下上下文: 我正在编写一个小浏览器游戏来练习我的网络技能和乐趣:) 有些用户拥有一些工厂和一个主仓库。这些生产不同类型的产品,这些产品存储在内部工厂仓库中。用户可以“聚集”工厂,将成品转移到他们的主仓库。
为了实现,我使用带有 PDO 的 PHP 作为数据库连接器。我的网络服务器使用 MySQL 数据库,而我的调试使用本地 Postgres 数据库。
用户应该能够在不点击收集链接并等待响应的情况下收集所有工厂。因此,我使用 Ajax,以便用户可以单击所有工厂一次并等待所有请求完成。为了防止这种并行访问在我的数据库中引入不一致,我使用了具有 SERIALIZABLE 隔离级别的事务。因为 pdo 不支持隔离级别,所以我在与我的 Postgres-db 的连接处发送一个查询
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET statement_timeout=10000;
第二个查询应该防止并行事务取消,而另一个事务正在进行。两个查询都没有返回错误,但不起作用。当我发送 8 个几乎并行的请求时,其中只有 2-3 个返回成功,另一个从 postgres “25P02 IN FAILED SQL TRANSACTION”返回错误。在我看来,在调试时,事务不会等待另一个完成,但我不确定。
现在我的问题:
- 是否可以通过 PDO 获得隔离级别和超时?
- 我可以使用任何替代品吗? (除了 Zend 这样的重量级框架,我想深入探索所有机制)
- 如果我只使用一种类型的数据库和像 mysqli 这样的专用连接器,我能解决我的问题吗?我认为使用 PDO 更灵活是个好主意,但可能不适合浏览器游戏。
- 我的数据库访问方法可以吗?还是有更好的设计?
- 这样的错误是否正常,这样的事务是否应该循环直到成功?如果是,在客户端使用 Ajax 还是在服务器端使用 PHP?
【问题讨论】:
-
您需要为
SELECT隔离事务? -
@feela :我的交易由两个选择组成,用于获取内部仓库和主仓库中的存储量,然后我用 php 处理这些并将它们写回数据库。为了显示工厂,我使用没有事务的查询。
-
这个问题太宽泛了。我将查看错误消息和原因;其余的是 Stack Overflow as per the FAQ
-
@CraigRinger :在您回答之后,我打开了所有日志记录功能,并且总是出现相同的错误,即事务被中止,因为另一个可序列化的事务(错误:“在识别为枢轴时取消,在冲突检查期间。”)。我认为可序列化事务相互等待的假设似乎是错误的。他们像旅鼠一样走向死亡;) PHP 没有线程,所以我不能使用工作线程来连续处理事务。所以只剩下我的第五个问题了。
-
@Gnietschow 是的,可序列化事务中的序列化错误是正常的。他们不会互相等待(“阻塞”);如果无法序列化事务,则除了一个冲突事务之外的所有事务都会中止。这在文档 (postgresql.org/docs/current/static/transaction-iso.html) 中有明确解释。您的应用程序必须准备好重试 任何 事务,无论是否可序列化,直到它从数据库收到成功的
COMMIT确认。
标签: php mysql ajax postgresql pdo