Javascript 对网页进行实时更新时跟踪更改的方法
我希望在网页上实时更新订单(和状态)列表。(MySQL)数据库中的订单通过其他进程(PHP)异步更新 我熟悉将数据推送到页面的机制(轮询、事件源)。这与此无关 我所要做的是弄清楚,在没有数据的情况下,每个用户到底需要推送哪些数据Javascript 对网页进行实时更新时跟踪更改的方法,javascript,php,mysql,atomicity,eventsource,Javascript,Php,Mysql,Atomicity,Eventsource,我希望在网页上实时更新订单(和状态)列表。(MySQL)数据库中的订单通过其他进程(PHP)异步更新 我熟悉将数据推送到页面的机制(轮询、事件源)。这与此无关 我所要做的是弄清楚,在没有数据的情况下,每个用户到底需要推送哪些数据 不必要地更新不需要更新的列表实体 没有遗漏更新 我的表确实有一个DateTime列last\u update\u date,当订单发生任何更改时,我会更新该列。我知道MySQL实际上没有任何可以触发其他代码的事件触发器 迄今为止的想法: 在我的JS中,我可以跟踪最后一个
last\u update\u date
,当订单发生任何更改时,我会更新该列。我知道MySQL实际上没有任何可以触发其他代码的事件触发器
迄今为止的想法:
我确信有一种更原子化的方法可以做到这一点,不过我只是画了一张空白。什么是适合这种情况的设计模式?您必须轮询数据库以获取更改,MySQL不能将更改推送到其他应用程序,这是正确的 诀窍是在整个轮询过程中使用服务器时间。使用表格跟踪轮询。例如,假设您的用户具有用户id值。然后制作一个
poll
表格,包括
user_id INT primary key
polldate DATETIME
然后,当你投票时,做这个序列
首先确保您的用户在poll
表中有一个条目,显示很久以前的polldate
。(INSERT IGNORE不会覆盖表中的任何现有行。)
检索所需的更新行;自上次更新以来的
SELECT t.whatever, t.whatelse
FROM transaction_table t
JOIN poll p ON t.user_id = p.user_id
WHERE user_id = @userid
AND t.last_update_date > p.polldate;
更新poll
表的polldate列
UPDATE poll p
SET p.polldate = IFNULL(MAX(t.last_update_date), p.polldate)
FROM transaction_table t
JOIN poll_p ON t.user_id = p.user_id
WHERE user_id = @userid
AND t.last_update_date > p.polldate;
并提交事务
COMMIT;
每次使用此序列时,您都会从事务
表中获取自上次轮询以来已更新的项目。如果没有项目,polldate
将不会更改。而且,这一切都是在服务器时间
您需要该事务,以防其他客户端更新SELECT和UPDATE查询之间的事务表行 O.Jones提供的解决方案可以使跟踪更新原子化,但如果在一秒钟内发生以下情况,则该解决方案会失败:
还是=
。这不是代码的错误,这是MySql datetime类型只有1秒分辨率的限制。MySql v8可以在一定程度上缓解这一问题,尽管这仍然不能保证原子性
我最终使用的解决方案是创建一个order\u changelog
表
CREATE TABLE 'NewTable' (
'id' int NULL AUTO_INCREMENT ,
'order_id' int NULL ,
'update_date' datetime NULL ,
PRIMARY KEY ('id')
);
每当对订单进行更改时,此表都会更新,基本上是对每次更新进行计算
对于客户端,服务器存储会话中发送的来自order\u changelog
的最后一个ID。每次客户端轮询时,我都会从order\u changelog
中获取ID大于会话中存储的ID的所有行,并将订单加入其中
$last_id = $_SESSION['last_update_id'];
$sql = "SELECT o.*, c.id as update_id
FROM order_changelog c
LEFT JOIN orders o ON c.order_id = o.id
WHERE c.id > $last_id
GROUP BY o.id
ORDER BY order_date";
我现在保证拥有自上次投票以来的所有订单,没有重复订单,而且我不必跟踪个别客户
CREATE TABLE 'NewTable' (
'id' int NULL AUTO_INCREMENT ,
'order_id' int NULL ,
'update_date' datetime NULL ,
PRIMARY KEY ('id')
);
$last_id = $_SESSION['last_update_id'];
$sql = "SELECT o.*, c.id as update_id
FROM order_changelog c
LEFT JOIN orders o ON c.order_id = o.id
WHERE c.id > $last_id
GROUP BY o.id
ORDER BY order_date";