Workerman MySQL 连接池

stephen

由于 workerman 的mysql组件在操作事物的时候需要在一个独立的db连接里面处理,如果相同的连接处理一个事物可能会造成异常,所以开发了一个db连接池,代码如下,如果有问题,欢迎交流指教
 

<?php

use Workerman\MySQL\Connection as DbConn;

class DbPool
{

    /**
     * db connection pool
     * @var resource
     */
    public static $_db = null;

    /**
     * db connection pool
     * @var array
     */
    public static $_dbs = [];

    /**
     * db mapping to pool
     */
    public static $_dbsPool = [];

    /**
     * 闲置分配和设置锁
     * @var boolean
     */
    public static $_idleLock = false;

    /**
     * 连接池默认数量
     * @var int
     */
    public static $_defaultDbConnPoolNum = 100;

    /**
     * make a db connection
     * @
     */
    public static function initDbConn()
    {
        if (self::$_db === null) {
            self::$_db = self::createDbConn();
        }
        return self::$_db;
    }

    /**
     * Create a new db connection
     * @return db instance
     */
    public static function createDbConn()
    {
        $config = $GLOBALS['app_conf']['db'];
        return new DbConn(
            $config['host'],
            $config['port'],
            $config['username'],
            $config['password'],
            $config['db_name']
        );
    }

    /**
     * Get a DB connection instance
     * @param mixed $useTrans Defaults to false
     * @return object The db connection instance
     */
    public static function getDB($useTrans = false)
    {
        if ($useTrans === false) {
            return self::initDbConn();
        }

        if (!isset(self::$_dbsPool[$useTrans])) {
            $index = self::getIdle($useTrans); // 获取置的连接,如果有,用闲置
            if ($index === false || !isset(self::$_dbs[$index])) {
                $index = 'dbConn_' . md5(microtime(true) . count(self::$_dbs));
                self::$_dbs[$index] = self::createDbConn();
            }
            self::$_dbsPool[$useTrans] = $index;
        } else {
            $index = self::$_dbsPool[$useTrans];
        }
        return self::$_dbs[$index];
    }

    /**
     * close db conn
     * @param mixed $useTrans defaults to false
     */
    public static function closeDB($useTrans = false)
    {
        if ($useTrans !== false and isset(self::$_dbsPool[$useTrans])) {
            if (count(self::$_dbs) > self::$_defaultDbConnPoolNum) {
                $index = self::$_dbsPool[$useTrans];
                self::$_dbs[$index]->closeConnection();
                self::$_dbs[$index] = null;
                unset(self::$_dbs[$index]);
                unset(self::$_dbsPool[$useTrans]);
            } else {
                self::setIdle($useTrans); // 将连接设置为闲置
            }
        }
        if ($useTrans === false) {
            self::$_db = null;
        }
    }

    /**
     * 从pool获取一个闲置的连接, 并赋值为指定的连接transToken
     * @return mixed 找到闲置则返回连接索引,否则返回false
     */
    private static function getIdle($transToken)
    {
        if (self::$_idleLock === true) {
            return;
        }
        self::$_idleLock = true;
        foreach (self::$_dbsPool as $key => $item) {
            if (strpos($key, 'idle_') === 0) {
                self::$_dbsPool[$transToken] = self::$_dbsPool[$key];
                unset(self::$_dbsPool[$key]);
                self::$_idleLock = false;
                return self::$_dbsPool[$transToken];
            }
        }
        self::$_idleLock = false;
        return false;
    }

    /**
     * 将一个连接设置为闲置
     */
    private static function setIdle($transToken)
    {
        if (self::$_idleLock === true) {
            return;
        }
        self::$_idleLock = true;
        if (isset(self::$_dbsPool[$transToken])) {
            $key = 'idle_' . md5(microtime(true));
            $tmp = self::$_dbsPool[$transToken];
            unset(self::$_dbsPool[$transToken]);
            self::$_dbsPool[$key] = $tmp;
        }
        self::$_idleLock = false;
    }
}
阅读 4648
0个评论

stephen

1925
积分
0
获赞数
0
粉丝数
2017-01-02 加入