首先,我写了一个小小的浏览器游戏来练习我的网络技能和乐趣:)有一些用户拥有一些工厂和一个主要的仓库。这些产品生产不同类型的产品,存储在内部工厂仓库中。用户可以“收集”工厂,将成品转移到他们的主仓库。
对于实现,我使用PHP与PDO作为数据库连接器。我的and服务器使用MySQL数据库,我的调试使用本地Postgres-数据库。
用户应该能够收集所有工厂,而无需单击聚集链接并等待响应。因此,我使用Ajax,以便用户只需单击所有工厂一次,并等待所有请求完成。为了防止这种并行访问将不一致引入我的数据库,我使用具有隔离级别SERIALIZABLE的事务。由于pdo不支持隔离级别,所以我在与Postgres-db的连接处发送一个查询
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET statement_timeout=10000;第二个查询应防止并行事务取消,而另一个事务正在进行中。这两个查询都不返回错误,但不工作。当我发送8个几乎并行的请求时,其中只有2-3个成功返回,另一个返回postgres "25P02在失败的SQL事务“中的一个错误。在调试过程中,在我看来,事务不会等待另一个事务完成,但我不确定这一点。
现在我的问题是:
发布于 2012-10-20 02:07:08
该错误告诉您,您在一个已经出错的事务中发出了一条语句。虽然前面的语句似乎没有失败,但它们可能已经失败了;PDO和PHP并没有以健壮和仔细的错误处理而闻名。
我强烈建议您在运行测试时检查PostgreSQL日志文件。看看什么失败了,在哪里。设置一个log_line_prefix可能很有帮助,通过显示后端进程id,您可以更容易地看到哪些语句来自哪个会话,如下所示:
log_line_prefix = 'ss=%e pid=%p cmd=%i'您还可能希望设置log_statement = all。
很可能您会看到PDO发出了一个产生错误的查询,所以您的下一个语句尝试在一个中止的事务中执行并生成25P02 in_failed_sql_transaction。
顺便说一句,这看起来并不像一个特别需要SERIALIZABLE隔离才能得到一致结果的用例。您考虑过只在两个UNION ALL中使用SELECT吗?
SELECT 'internal', count(inventory_items) FROM internal_inventory
UNION ALL
SELECT 'main', count(inventory_items) FROM main_inventory;或者如果模式更好:
SELECT isinternal, count(inventory_items)
FROM inventory
GROUP BY isinternal;https://stackoverflow.com/questions/12971627
复制相似问题