有这么一个需求:生成文件的时候,由于多用户都有权限进行生成,防止并发下,导致生成的结果出现错误,需要对生成的过程进行加锁,只容许一个用户在一个时间内进行操作,这个时候就需要用到锁了,将这个操作过程锁起来。在用了cache的时候,cache失效可能导致瞬间的多数并发请求穿透到数据库此时也可以得需要用锁在同一并发的过程中将这个操作锁定。
针对以上的2种情况,现在的解决方法是对处理过程进行锁机制,通过PHP实现如下:
用到了Eaccelerator的内存锁和文件锁,原理:判断系统中是否安了EAccelerator如果有则使用内存锁,如果不存在,则进行文件锁。根据带入的key的不同可以实现多个锁直接的并行处理,类似Innodb的行级锁。
具体类如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | <?php
class CacheLock
{
private $path = null;
private $fp = null;
private $hashNum = 100;
private $name ;
private $eAccelerator = false;
public function __construct( $name , $path = 'lock\\' )
{
$this ->eAccelerator = function_exists( "eaccelerator_lock" );
if (! $this ->eAccelerator)
{
$this ->path = $path .( $this ->_mycrc32( $name ) % $this ->hashNum). '.txt' ;
}
$this ->name = $name ;
}
private function _mycrc32( $string )
{
$crc = abs (crc32( $string ));
if ( $crc & 0x80000000) {
$crc ^= 0xffffffff;
$crc += 1;
}
return $crc ;
}
public function lock()
{
if (! $this ->eAccelerator)
{
$this ->fp = fopen ( $this ->path, 'w+' );
if ( $this ->fp === false)
{
return false;
}
return flock ( $this ->fp, LOCK_EX);
} else {
return eaccelerator_lock( $this ->name);
}
}
public function unlock()
{
if (! $this ->eAccelerator)
{
if ( $this ->fp !== false)
{
flock ( $this ->fp, LOCK_UN);
clearstatcache();
}
fclose( $this ->fp);
} else {
return eaccelerator_unlock( $this ->name);
}
}
}
?>
|
登录后复制
使用如下:
1 2 3 4 5 | $lock = new CacheLock( 'key_name' );
$lock ->lock();
$lock ->unlock();
|
登录后复制
http://www.bkjia.com/PHPjc/752442.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/752442.htmlTechArticle有这么一个需求:生成文件的时候,由于多用户都有权限进行生成,防止并发下,导致生成的结果出现错误,需要对生成的过程进行加锁,...