用多线程处理数据时,常常会出现数据结果不一致的情况。比如两个线程处理同一个订单赠送积分,可能会赠送两次,这时候我们希望一个订单被一个线程获取后,就不要再被其它线程处理了。我们只需要在第一个线程获取了订单信息后加一个排他锁,其它线程再去获取该订单的时候获取锁状态,如果有锁就会直接丢弃不处理,否者再去处理。
锁机制根据实现方式可以分为数据库锁和文件锁
1,文件锁
$file = '1.lock';
$fp = fopen($file,'a');
if(flock($fp, LOCK_EX|LOCK_NB)){
echo 'I Get It';
// do something
flock($fp, LOCK_UN)
}else{
echo 'I Lost It'
}
说明:
LOCK_EX 为要取得排它锁,LOCK_NB 为锁定时程序不阻塞 LOCK_UN 为程序处理完后解锁操作
封装成函数
/**
* 程序锁
* @param string $operation 锁定操作,默认 1为锁定操作,0 为解锁
* @param string $name 锁定文件名
*/
function program_lock($operate = 1, $name = 'default'){
static $fp = null;
$dir = './tmp/';
if(!is_dir($dir)){
@mkdir($dir,'0777');
}
$file = $dir.$name.'.lock';
if(!is_file($file)){
touch($file);
}
if(is_null($fp)){
$fp = fopen($file,'r+');
}
if(empty($operate)){
$res = flock($fp, LOCK_UN);
fclose($fp);
$fp = null;
return $res;
}else{
if(flock($fp, LOCK_EX | LOCK_NB)){
return true;
}else{
return false;
}
}
}