php - 如何从浏览器游戏设计数据库访问

标签 php mysql ajax postgresql pdo

首先是一点背景: 我正在写一个小浏览器游戏来练习我的网络技能和乐趣 :) 有些用户拥有一些工厂和一个主要仓库。这些生产不同类型的产品,存储在内部工厂仓库中。用户可以“集合”工厂将成品转移到他们的主要仓库。

为了实现,我使用带有 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”。在调试时,在我看来,事务不会等待另一个事务完成,但我不确定这一点。

现在我的问题:

  1. 是否有可能获得与 PDO 一起使用的隔离级别和超时?
  2. 有没有我可以使用的替代品? (除了像 Zend 这样的重量级框架,我想从深层探索所有机制)
  3. 如果我只使用一种类型的数据库和像 mysqli 这样的专用连接器,我能解决我的问题吗?我认为使用 PDO 更灵活是个好主意,但它可能不适合浏览器游戏。
  4. 我的数据库访问方法可以吗?还是有更好的设计?
  5. 这样的错误是否正常,这样的交易应该循环直到成功吗?什么时候是,在客户端使用 Ajax 还是在服务器端使用 PHP?

最佳答案

该错误告诉您,您在已经出错的交易中发出声明。虽然之前的陈述似乎并没有失败,但它们可能已经失败了; PDO 和 PHP 并不以健壮和谨慎的错误处理而著称。

我强烈建议您在运行测试时检查 PostgreSQL 日志文件。看看什么地方失败了。设置 log_line_prefix 可能会有所帮助,这样您就可以通过显示后端进程 ID 更轻松地查看哪些语句来自哪些 session ,例如:

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;

关于php - 如何从浏览器游戏设计数据库访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12971627/

相关文章:

javascript - AJAX url路径问题

java - 使用 jsf 和 A​​jax 更改输入值

mysql查询的PHP while循环有时会随机返回一个空集(它们不为空,但结果为空)

php - 使用 foreach() 从 PHP 数组值更新 SQL 数据库表

mysql - 将 2 周添加到日期 SQL

mysql - SQL - 将特定 ID 列表插入到表中

带有 POST 或 PUT 的 jQuery.ajax 没有 IE8 和 IE9 的响应 header

javascript - target 属性的 CSS 版本

php - 回显 HTML 链接

c# - 使用MySql内连接在谷歌饼图上显示数据