我有一个 LAPP(linux、apache、postgresql 和 php)环境,但问题在 Postgres 或 Mysql 上都非常相同。
我开发了一个 cms 应用程序,用于处理客户、文档(估算、发票等)和其他数据,在 1 个 postgres 数据库中构建,具有许多模式(每个使用该应用程序的客户都有一个);让我们假设大约有 200 个模式,每个模式由 15 人(平均)同时使用。
编辑 :我确实在每个表上都有一个名为 last_update 的时间戳字段,以及一个每次更新行时都会更新时间戳的触发器。
情况是:
我想要的情况:
我想知道使用 ajax 来做到这一点;只需使用带有文档 id 和上次更新时间戳的隐藏字段,每 5 秒检查上次更新时间是否相同并且什么都不做,否则,显示警告对话框。
因此,页面 check-last-update.php 应该类似于:
<?php
//[connect to db, postgres or mysql]
$documentId = isset($_POST['document-id']) ? $_POST['document-id'] : 0;
$lastUpdateTime = isset($_POST['last-update-time']) ? $_POST['last-update-time'] : 0;
//in the real life i sanitize the data and use prepared statements;
$qr = pg_query("
SELECT
last_update_time
FROM
documents
WHERE
id = '$documentId'
");
$ray = pg_fetch_assoc($qr);
if($ray['last_update_time'] > $lastUpdateTime){
//someone else updated the document since i opened it!
echo 'reload';
}else{
echo 'ok';
}
?>
但我不喜欢每 5 秒为每个打开一个(或多个...)文档的用户强调 db。
那么,在不破坏数据库的情况下,还有什么有效的解决方案?
我想使用文件,例如为每个文档创建一个空的 txt 文件,每次更新文档时,我都会“触摸”更新“上次修改时间”的文件......但我想这会更慢比 db 并在我有很多用户编辑同一文档时出现问题。
如果其他人有更好的想法或任何建议,请详细描述!
* - - - - - 更新 - - - - *
我绝对选择不点击数据库来检查“上次更新时间戳”,不要介意查询是否很快,(主)数据库服务器还有其他任务需要完成,不喜欢增加他对那件事的过载的想法.
所以,我采取这种方式:
另一个编辑:
该文件的方式不起作用。
APC 可以成为解决方案。
命中数据库也可以是解决方案,创建一个表来处理时间戳(只有两列,document_id 和 last_update_timestamp),需要尽可能快和轻。
长轮询:我会选择这种方式,在apache下使用lighttpd来加载静态文件(图片、css、js等),并且只针对这种类型的长轮询;这将减轻 apache2 的负载,特别是对于轮询。
Apache 会将所有这些请求代理到 lighttpd。
现在,我只需要在 db 解决方案和 APC 解决方案之间做出决定..
ps:感谢所有已经回答我的人,你真的很有用!
最佳答案
我同意我可能不会为此访问数据库。我想我会使用 APC 缓存(或其他一些内存缓存)来维护这些信息。您所描述的显然是详细记录级别的乐观锁定。数据库结构中的级别越高,您需要处理的就越少。听起来您想检查结构中的多个表。
我会维护一个缓存(在 APC 中)的 ID 和由表名键控的上次更新时间的时间戳。例如,我可能有一个表名数组,其中每个条目都以 ID 为键,实际值是最后更新的时间戳。可能有很多方法可以用数组或其他结构来设置它,但你明白了。我可能会向缓存添加超时,以便在一段时间后删除缓存中的条目 - 即,我不希望缓存增长并假设 1 天前的条目不再有用)。
使用此架构,您需要执行以下操作(除了设置 APC):
关于php - 处理并发问题的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1779317/