在新浪云SAE上实现PHP锁机制,简单解决并发问题

很多时候需要让系统的某些操作串行化,如抢购(先到先得)、报名等,这个时候就要对这些操作来加上一把锁。(好比上厕所,需要挨个来,待你用完之后把门打开,别人再进去,保证厕所永远只有1个人, 上厕所的过程是串行化的)

也许通过文件(加锁创建一个文件/解锁再删掉,或直接使用flock函数) 或者 MySQL结合InnoDB引擎 去实现,方法也比较多。但个人感觉都不是很优秀,尤其在新浪云SAE这种不支持IO的PaaS上,文件锁的实现方式是不能用的。

在SAE,其实有非常多的方法、很简单的实现这个需求,这里写个利用 Counter 服务模拟锁的实现方法:

<?php

class Lock {

    const LKEY = 'GOLD_LOCK';

    static private $ct = NULL;

    //初始化操作,取得计数器实例,如果计数器不存在则创建
    static public function init() {
        is_null(self::$ct) && self::$ct = new SaeCounter();
        self::$ct->exists(self::LKEY) || self::$ct->create(self::LKEY);
    }   

    //加锁
    static public function add() {
        self::init();
        return self::$ct->set(self::LKEY, 1); 
    }   

    //开锁
    static public function del() {
        self::init();
        return self::$ct->set(self::LKEY, 0); 
    }   

    //获取锁状态
    static public function get() {
        self::init();
        return self::$ct->get(self::LKEY) > 0;
    }   
}

//1、判断是否已加锁
if (Lock::get()) {
    /*
     * 这里可以直接exit
     * 也可以while写个死循环结合sleep,实现类似小米抢购的那种等待状态,在服务器内部进行排队抢购
     * ....
     * ....
     */   
} 

//2、加锁
Lock::add();

/*
 * 这里就是你业务逻辑代码
 * ....
 * ....
 */

//3、开锁
Lock::del();

Counter是SAE为开发者提供的计数器服务,用来实现高并发情景下的计数功能。用户可以在控制面板或程序中创建计数器,通过API对计数器进行设置,加减和统计。
Counter简化了计数应用的开发.开发者可以轻松实现高并发情景下的计数功能,实现如兔年春晚投票,广告渠道访问计数等应用,同时可以使用Counter的统计功能轻松实现数据汇总。

你可以通过SAE的KVDB、Memcache 等服务,轻松实现串行,当然还有专门为队列而生的 TaskQueue,这里就不一一介绍了

Related post

微信公众号:程序员到架构师

最新文章

Return Top