在一段更新数据库的代码中,居然出现了虚假的更新动作。
数据库用的是MySql,测试环境是局域网,4核机器,Mysql无事务机制,无存储过程;PHP5.2.x。
这段代码需要更新超过300条记录。
每次更新完自己后,需要调用JobManage::synchroJobStatus做同步,同步过程中有一次数据库操作。
<?php
$ibegin=0;
while (true) {
$sql = "SELECT JI_ID FROM tb_job_info WHERE JI_CompanyID={$companyID} LIMIT {$ibegin},100";
$jobList = DB::sql($sql, DBName_company);
if (empty($jobList)) {
break;
}
foreach ($jobList as $job){
$data = array(
'JS_IsAdminChecked' => $status,
'JS_AdminCheckedRemark' => $remark,
'JS_AdminCheckedTime' => time(),
);
$where = array('JS_JobID' => $job["JI_ID"]);
$statusInfo = DB::getRow('tb_job_status', $where, DBName_company,'JS_JobID');
if(empty($statusInfo)){
$iRnt = $this->addJobStatus($job['JI_ID'],$status,$remark);
if($iRnt<0){
return 0;
}
}
$iRtn += DB::edit('tb_job_status', $data, $where, DBName_company);
$statusInfo = array_merge($statusInfo,$data);
$data = array(
'LC_Type' => $isAdminCheck,
'LC_AdminID'=>$checkAdminID,
'LC_CheckStatus' => $status,
'LC_HitWords' => $remark,
'LC_UpdateTime' => time()
);
$where = array('LC_CompanyID' => $companyID,'LC_JobID' =>$job["JI_ID"]);
$exist = DB::getRow('tb_log_checkjob',$where,DBName_company,'LC_CompanyID');
if(!empty($exist)){
DB::edit('tb_log_checkjob',$data,$where,DBName_company);
}else{
$data = array_merge($data,$where,array('LC_AddTime' => time()));
$result = DB::add('tb_log_checkjob',$data,DBName_company);
}
JobManage::synchroJobStatus($statusInfo);
}
$ibegin+=100;
}
?>
更新的语句关键是这条:DB::edit('tb_job_status', $data, $where, DBName_company);
上面的问题是:
1.查询数据库,一轮300多条记录中,有100多条记录的该语句没有生效。
2.这条语句每次都返回了更新成功。
3.数据能够完整的读取,没有遗漏。
经过修改:
<?php
//$ibegin=0;
//while (true) {
$sql = "SELECT JI_ID FROM tb_job_info WHERE JI_CompanyID={$companyID}";// LIMIT {$ibegin},100";
$jobList = DB::sql($sql, DBName_company);
//if (empty($jobList)) {
// break;
//}
foreach ($jobList as $job){
$data = array(
'JS_IsAdminChecked' => $status,
'JS_AdminCheckedRemark' => $remark,
'JS_AdminCheckedTime' => time(),
);
$where = array('JS_JobID' => $job["JI_ID"]);
$statusInfo = DB::getRow('tb_job_status', $where, DBName_company,'JS_JobID');
if(empty($statusInfo)){
$iRnt = $this->addJobStatus($job['JI_ID'],$status,$remark);
if($iRnt<0){
return 0;
}
}
$iRtn += DB::edit('tb_job_status', $data, $where, DBName_company);
$statusInfo = array_merge($statusInfo,$data);
$data = array(
'LC_Type' => $isAdminCheck,
'LC_AdminID'=>$checkAdminID,
'LC_CheckStatus' => $status,
'LC_HitWords' => $remark,
'LC_UpdateTime' => time()
);
$where = array('LC_CompanyID' => $companyID,'LC_JobID' =>$job["JI_ID"]);
$exist = DB::getRow('tb_log_checkjob',$where,DBName_company,'LC_CompanyID');
if(!empty($exist)){
DB::edit('tb_log_checkjob',$data,$where,DBName_company);
}else{
$data = array_merge($data,$where,array('LC_AddTime' => time()));
$result = DB::add('tb_log_checkjob',$data,DBName_company);
}
JobManage::synchroJobStatus($statusInfo);
}
//$ibegin+=100;
//}
?>
问题不再存在· ·
何种原因,导致这个错误出现呢?
初步断定 Limit 出现了这个误差!
具体如何产生的,还有待分析。
分享到:
相关推荐
MySQL中的`DELETE`语句是用于从数据库表中删除数据的关键操作。然而,在大量数据处理时,直接使用`DELETE`可能会导致性能问题,因为它可能会锁定整个表,影响其他并发操作。这就是`DELETE ... LIMIT`语句的作用,它...
commen sence指的是那些大家都应该知道的事情,但往往大家又会会略这些东西,或者对这些东西一知半解,今天我总结下自己在mysql中遇到的一些commen sense类型的问题。 1、varchar(5)可以存储多少个汉字,多少个...
mysql> select * from MyClass order by id limit 0,2; 或者: mysql> select * from MyClass limit 0,2; 6、删除表中数据 命令:delete from 表名 where 表达式 例如:删除表 MyClass中编号为 的记录 mysql>...
4) 传统的分页, 分段式分页(每页内分为多段)归根结底是对数据集做一次切割, 映射到mysql的sql语法上, 就是根据输入求得limit子句, 适用场景为数据集变化频率低 5) since_id类分页, 其本质是假定已有数据无变化, 将...
由于任务存在派发时间,所以任务运行的时间可能会有1-2秒的误差。 windows下执行任务在循环里,编写任务有问题或调用exit将导致后台脚本停止,linux下无此问题。 建议生产部署在linux下运行多进程模式,因为运行在多...
cur.execute("SELECT * FROM station_snapshot LIMIT 10") for row in cur.fetchall(): print(row) except Exception as e: print("Error:", e) finally: cur.close() db.close() ``` ##### 4. 数据格式化...