简而言之
是否有一种安全的方法将数据库条目 - 基于时间戳条件 - 移动到另一个表(无需先查询时间(?为了确保它,INSERT INTO
与DELETE
完全相同的条目上工作?
问题的背景
- 这个问题不是关于使用交易的重要性,这是一个给定的!而是关于两个后续查询的时间(例如
NOW()
的值(可能不同的问题。 - 由于使用了编程框架,它(出于安全原因(不允许在单个调用中执行多个查询,这实际上成为一个问题
示例表结构
Source
---------------------------------------------
ID | Timeout | Data
---------------------------------------------
1 | 2014-12-31 12:00:00 | foo
2 | 2014-12-31 15:00:00 | bar
3 | 2014-12-31 18:00:00 | foobar
Archive
---------------------------------------------
ID | Data
---------------------------------------------
演示(简体(
<?php
beginTransaction();
try {
// Imagine this happens at 2014-12-31 14:59:59(.992) [Entry #2 not copied]
execute( "INSERT INTO Archive (ID, Data)
SELECT ID, Data FROM Source
WHERE Timeout <= NOW()" );
// While here it might be already 2014-12-31 15:00:00(.004) [Entry #2 deleted]
execute("DELTE FROM Source WHERE Timeout <= NOW()");
commit();
}
catch (Exception $e) {
rollBack();
return false;
}
return;
?>
那么有没有一种安全的方法可以避免这个问题,最好考虑到性能(我知道,在这种情况下,php 可能首先是错误的语言^^(。非常感谢帮助!
execute("SET @now = NOW()");
execute("
INSERT INTO Archive (ID, Data)
SELECT ID, Data
FROM Source
WHERE Timeout <= @now
");
execute("DELTE FROM Source WHERE Timeout <= @now");
或
execute("
INSERT INTO Archive (ID, Data)
SELECT ID, Data
FROM Source
WHERE Timeout <= NOW()
");
execute("DELTE FROM Source WHERE Timeout <= (SELECT MAX(Timeout) FROM Archive)");