在一个表中插入数据,从另一个表中删除数据,并在 mysql 中使用时间戳条件


Insert data in one table, remove from another, with timestamp condition in mysql

简而言之

是否有一种安全的方法将数据库条目 - 基于时间戳条件 - 移动到另一个表(无需先查询时间(?为了确保它,INSERT INTODELETE完全相同的条目上工作?

问题的背景

  • 这个问题不是关于使用交易的重要性,这是一个给定的!而是关于两个后续查询的时间(例如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)");