我遇到以下问题。
我在 MySql 数据库上有一个表 INNODB,它接收连续的数据流。
该表有一个复合索引datetime-deviceID
、一个字段“data”和一个字段“sending”
我正在编写一个必须执行此操作的 PHP 脚本:
- 选择所有尚未发送的行 (sent=0)。 (MySQL 上的 php 查询)
- 将选定的列存储在 PHP 数组中。 (php)
- 对 deviceID 进行转换 (php)
- 将具有唯一插入的行发送到另一个数据库。
- 通过一次操作更新所有先前选择的行(点 1),并将发送的字段从 0 更新为 1。
我的问题是在第 4 点上,我不能冒险在第 1 点和第 4 点之间到达额外的数据,这会导致数据丢失,因为这些数据永远不会发送到接收器表。
为了我想必须在第 1 点之前锁定表,直到所有过程结束,但我对事务不太熟悉,我需要一些帮助。
我正在寻找这段代码来满足我的需求 - 我的方法正确吗?
START TRANSACTION;
SELECT value FROM table WHERE sended = 0 FOR UPDATE;
UPDATE table SET sended = 1 WHERE sended = 0;
COMMIT;
我是否能够通过 php 检索从 SELECT 操作中选择的列或受 UPDATE 影响的列,以及如何确保选择的列与更新的列相同?
最佳答案
可能的解决方案之一:
- 向表添加代理主键,使其为bigint unsigned auto_increment (您可以使用 UUID ,但随后您需要更改插入语句或创建触发器)
- 当前主键更改为唯一索引
- 如果字段是 auto_increment,则您系统中的此表不需要任何其他 SQL 查询
- 在此特定脚本中,除了当前列之外,您还需要获取它
- 发送到另一个数据库后将此 ID 存储在单独的数组中
- 在最后阶段,您需要执行以下查询:
$updateSQL = 'update table set sended=1 where ID in (' . implode(',',$sentIDs).') and sended=0' ;
- 它将更新仅具有适当 ID 且未发送的所有记录(实际上第二个条件是可选的,只是我的习惯)
关于php - 更新先前使用 MYSQL 和 PHP 选择的一组行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19865275/