我有一个使用数据库表作为缓冲区的脚本。
它首先从另一个表中提取对象列表,然后运行一个循环,为每个对象调用 API。对于每个 API 答案,我使用当前迭代对象的键和相应的数据以及该对象键的删除语句在缓冲表中创建一条插入语句。然后,我首先运行删除操作以将该对象的记录从表中取出,然后插入新的数据。
这种情况大约每 5 分钟发生一次,脚本运行大约 2 分钟。我遇到的问题是我从表中删除了所有元素。我用R studio查了数据,大约每5分钟波动一次。
由于它会在每个对象的调用上删除,因此如果此删除导致问题,则表将始终为空。如果一切都按顺序运行。
这是运行单个对象调用的函数:
function singleProp( $pId , $wispId , $nasId , $req){
$res_j = apiCall( $wispId , $nasId );
$count = get_value_by_tag($res_j , "COUNT" );
$aps = array();
$no_down = 0;
$db_con = new db_connector();
$db_con->connect();
$stmt_d = $db_con->dblink->prepare( "DELETE FROM ap_down WHERE prop_id = ? ;" );
$stmt_d->bind_param("i",$pId);
$stmt_d->execute();
$stmt_i = $db_con->dblink->prepare("INSERT INTO ap_down ( prop_id , ip , prop_type , description , time ) VALUES (?,?,?,?,now());");
for( $i = 1 ; $i <= $count ; $i++ ){
if( get_value_by_tag($res_j , "APSTATUS" , $i ) == "DOWN" ){
$stmt_i->bind_param("issd" , $pId , get_value_by_tag( $res_j , "ACCESSPOINTS" , $i ) , $req , get_value_by_tag( $res_j , "DESCRIPTION" , $i ) );
$stmt_i->execute();
$no_down ++ ;
}
}
}
你们有什么想法、建议或其他可能想查看的数据吗?
编辑:使用准备好的语句,因为它更安全并且更易于阅读。 编辑:代码缩进......因为很重要。
最佳答案
您的问题似乎是对 ap_down
表的并发访问之一。您应该确保所有操作都与其他操作隔离。
阅读过程:
LOCK TABLES ap_down READ;
SELECT ...;
UNLOCK TABLES;
编写过程(您的脚本):
LOCK TABLES ap_down WRITE;
DELETE ...;
INSERT ...;
UNLOCK TABLES;
您可以以不同的方式执行写入过程,以便仅在插入时锁定,并在锁定后立即删除:
// Do not lock -- yet.
$stmt_d = $db_con->dblink->prepare( "DELETE FROM ap_down WHERE prop_id = ? ;" );
$stmt_d->bind_param("i",$pId);
// Do not execute deletion -- yet.
$deleted = false;
$stmt_i = $db_con->dblink->prepare("INSERT INTO ap_down ( prop_id , ip , prop_type , description , time ) VALUES (?,?,?,?,now());");
for( $i = 1 ; $i <= $count ; $i++ ){
if ( get_value_by_tag($res_j , 'APSTATUS', $i ) != 'DOWN' ){
continue;
}
$db_con->dblink->query('LOCK TABLES ap_down WRITE;');
if (!$deleted) {
$deleted = true;
$stmt_d->execute();
}
$stmt_i->bind_param('issd', $pId, get_value_by_tag( $res_j, 'ACCESSPOINTS', $i ), $req , get_value_by_tag( $res_j, 'DESCRIPTION', $i ) );
$stmt_i->execute();
$db_con->dblink->query('UNLOCK TABLES;');
$no_down ++ ;
}
if (!$deleted) {
// Delete without locking.
$deleted = true;
$stmt_d->execute();
}
关于php mysql 操作顺序,似乎删除是一次性发生的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25331591/