php 关于锁的一些看法

背景:在一个项目中,需要一次对数据很复杂的计算,其中一次计算需要花费大概30秒钟时间,大概需要查询一个比较大的表300次左右,然后还需要进行查询7-8次数据库,然后进行组合排序等功能,完成最终结果。对于一个估算平均10w次的一个接口来说,无论从时间上讲和对于数据库的压力来说,这是完全不能接受的,但很幸运的是我们的需求只要求数据每天更新一次。

为此我们有了三种方法

第一种方案:这个方案是我一个同事提出,对300次查询进行优化,把计算结果规为一个表的一个属性,每天定时脚本得出这个属性,,这样查询只需7-8次就能完成。

第二种方案:这个方案是我另一个同事提出,对整个结果进行存储,这样就需要一句sql就能搞定,但是每天需要有一次比较长的查询排序放在一个结果表里面。

第三种方案:是我提出,为什么不把数据放在一个文件里面呢,这样数据库一次查询都没有了,不是降低了每天10w次的访问吗?于是我同事跟我说到进程同步问题,我很是迷茫,php不是有加锁功能吗?为什么不能放在一个文件里面,在使用file_put_content 加入LOCK_EX不是能预防读写锁问题吗。随着数据的增多,为什么一定要用数据库呢,几乎所有的瓶颈都是数据库上面,为什么不能尽量减少数据库的负担呢。于是我做了以下一些实验。

编写两个程序

process1:

set_time_limit(-1);
$filename="D://text.txt";
for($i=0;$i<100;$i++){
file_put_contents($filename, $i,FILE_APPEND|LOCK_EX);
sleep(1);
}

process2:

<?php
set_time_limit(-1);
$filename="D://text.txt";
$string = file_get_contents($filename);
for($i=0;$i<100;$i++){
    if(empty($string)){
        echo error_get_last().var_dump($string).'<br>';
    }else{
        echo $string."<br>";
    }
    sleep(1);
}

因为使用不同浏览器验证,我不知道这会不会产生什么影响。但是结果却是加锁后proceess2只能获得未加锁的内容。还是找不到关于为什么不能使用文件的原因,如果说数据完整和一致性管理上,第三种方法有他的劣势。但是我觉得跟进程无关。希望有人能回答我这些问题

另附我查询到的一些php锁资料

 

flock

(PHP 3 >= 3.0.7, PHP 4, PHP 5)

flock -- 轻便的咨询文件锁定

说明

bool flock ( int handle, int operation [, int &wouldblock] )

PHP 支持以咨询方式(也就是说所有访问程序必须使用同一方式锁定, 否则它不会工作)锁定全部文件的一种轻便方法。

注: 在 Windows 下 flock() 将会强制执行。

flock() 操作的 handle 必须是一个已经打开的文件指针。operation 可以是以下值之一:

 

    • 要取得共享锁定(读取程序),将 operation 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1)。

    • 要取得独占锁定(写入程序),将 operation 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2)。

    • 要释放锁定(无论共享或独占),将 operation 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3)。

    • 如果你不希望 flock() 在锁定时堵塞,则给 operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)。

 

posted @ 2013-12-14 23:58  暗痛  阅读(1233)  评论(0编辑  收藏  举报