由于 workerman?的mysql組件在操作事物的時(shí)候需要在一個(gè)獨(dú)立的db連接里面處理,如果相同的連接處理一個(gè)事物可能會造成異常,所以開發(fā)了一個(gè)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 = [];
/**
* 閑置分配和設(shè)置鎖
* @var boolean
*/
public static $_idleLock = false;
/**
* 連接池默認(rèn)數(shù)量
* @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); // 將連接設(shè)置為閑置
}
}
if ($useTrans === false) {
self::$_db = null;
}
}
/**
* 從pool獲取一個(gè)閑置的連接, 并賦值為指定的連接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;
}
/**
* 將一個(gè)連接設(shè)置為閑置
*/
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;
}
}