Liny_@NotePad

沉迷ACG中

PHP文件锁

YOYO posted @ 2010年9月21日 07:05 in 【PHP】 with tags io , 2869 阅读

由于没有application,只能用数据库、文件或共享内存来模拟,
但是数据库的话恐怕会并发,又找不到怎样加锁,共享内存在WINDOWS下仿佛不好用,
同事提到说可以用线程锁,查了下资料,需要服务器的管理权限,只得作罢,最后决定用文件锁来实现生成年月日-自动编号的主键。

那么代码如下:

$StudentID = date('ymd');
$fp = fopen("student.lock", "r");

flock($fp, LOCK_EX) or die("lock error");
$rs = $access->exec("SELECT MAX(StudentID) FROM Student WHERE StudentID LIKE '".$StudentID."___'");
if ($access->eof($rs)) 
{
	$StudentID = $StudentID."001";
}
else
{
	$theid = $access->get($rs, 0);
	$theid = substr($theid, 6, 3);
	$theid = (int) $theid;
	$theid = $theid + 1;
	if ($theid < 100) $theid = "00".$theid;
	else if ($theid < 10) $theid = "0".$theid;
				
	$StudentID = $StudentID.$theid;
}
			
$query = "INSERT INTO Student(StudentID) VALUES ('".$StudentID."');";
$access->exec($query);
flock($fp, LOCK_UN);
fclose($fp);

其他的记录就在解锁后根据已获得的主键自行updated,避免阻塞过久。

p.s. 里面的$access是封装的一个Access操作类的实例,如字面意义。

顺便总结下flock参数的意义:

第一个参数当然是文件指针,第二个参数可以是LOCK_EX(写锁/排他锁)、LOCK_SH(读锁/共享锁),如果要不被阻塞,要加上|LOCK_NB(不阻塞),解锁时则统一用LOCK_UN。

排它锁和共享锁的实际应用和数据库里的定义一样吧……在此不再赘述。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter