简体   繁体   English

SELECT然后立即DELETE mysql记录

[英]SELECT then immediately DELETE mysql record

I have a PHP script that runs a SELECT query then immediately deletes the record. 我有一个运行SELECT查询的PHP脚本,然后立即删除该记录。 There are multiple machines that are pinging the same php file and fetching data from the same table. 有多台机器正在ping同一个php文件并从同一个表中获取数据。 Each remote machine is running on a cron job. 每台远程计算机都在cron作业上运行。

My problem is that sometimes it is unable to delete fast enough since some of the machines ping at the exact same time. 我的问题是,有时它无法快速删除,因为有些机器在同一时间ping。

My question is, how can I SELECT a record from a database and have it deleted before the next machine grabs it. 我的问题是,我如何从数据库中选择一条记录,并在下一台机器抓取它之前将其删除。 For right now I just added a short delay but it's not working very well. 现在我只是添加了一个短暂的延迟,但效果并不好。 I tried using a transaction, but I don't think it applies here. 我尝试过使用交易,但我不认为这适用于此。

Here is an example snippet of my script: 这是我的脚本的示例片段:

<?php

$query = "SELECT * FROM `queue` LIMIT 1";
$result = mysql_query($query) or die(mysql_error());

while($row = mysql_fetch_array($result)){
    $email = $row['email'];
    $campaign_id = $row['campaign'];
}

$queryx = "DELETE FROM `queue` WHERE `email` = '".$email."'";
$resultx = mysql_query($queryx) or die(mysql_error());

?>

Really appreciate the help. 真的很感激帮助。

well I would use table locks read more here 好吧,我会在这里使用表锁更多

Locking is safe and applies to one client session. 锁定是安全的,适用于一个客户端会话。 A table lock protects only against inappropriate reads or writes by other sessions. 表锁仅保护其他会话不适当的读取或写入。

If you're using MariaDB 10: 如果您正在使用MariaDB 10:

DELETE FROM `queue` LIMIT 1 RETURNING *

Documentation . 文档

You should use subquery as follows... 您应该使用子查询如下...

<?php

$queryx = "DELETE FROM `queue` WHERE `email` IN (SELECT email FROM `queue` LIMIT 1)";
$resultx = mysql_query($queryx) or die(mysql_error());

?>

*Note: Always select only the fields you want... try to avoid select *... this will slow down the performance *注意:始终只选择您想要的字段...尽量避免选择* ...这会降低性能

run an update query that will change the key before you do your select. 运行更新查询,在您执行选择之前更改密钥。 Do the select by this new key, whicj is known only in the same session. 通过这个新密钥进行选择,只在同一个会话中知道。
If the table is innoDB the record is locked, and when it will be released, the other selects won't find the record. 如果表是innoDB,则记录被锁定,当它被释放时,其他选择将找不到记录。

Put your delete queries inside the while loop, just incase you ever want to increase the limit from your select. 将删除查询放在while循环中,只是因为你想要增加select的限制。

<?php
$query = mysql_query("SELECT * FROM `queue` LIMIT 1") or die(mysql_error());

while($row = mysql_fetch_array($query)){
    mysql_query("DELETE FROM `queue` WHERE `email` = '" . $row['email'] . "' LIMIT 1") or die(mysql_error());
}
?>

The above code would be just the same as running: 上面的代码与运行的代码相同:

mysql_query("DELETE FROM `queue` LIMIT 1") or die(mysql_error());

Be careful using your delete query, if the email field is blank, it will delete all rows that have a blank email. 使用删除查询时要小心,如果电子邮件字段为空,则会删除所有包含空白电子邮件的行。 Add LIMIT 1 to your delete query to avoid multiple rows being deleted. LIMIT 1添加到删除查询中以避免删除多行。

To add a random delay, you could add a sleep to the top of the script, 要添加随机延迟,您可以在脚本顶部添加一个睡眠

eg: 例如:

<?php
$seconds = mt_rand(1,10);
sleep($seconds);
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM