导致DB PDO连接失败的原因:SQLSTATE [1040]连接太多

时间:2013-10-27 21:05:39

标签: php mysql database pdo

我已经被这个错误困扰了几天,我找不到办法解决它。我试图实施

  • 单例数据库对象
  • 查询后关闭我的连接
  • 尝试持久连接
  • 将最大连接数设置为250(本地)
  • 设置最大用户连接数250(在本地)

这是否发生在其他人身上?


奇怪的是我的本地服务器上的错误消息是Connection failed: SQLSTATE[08004] [1040],但行仍然是插入和数据库查询工作。

在生产服务器上,错误消息变为Connection failed: SQLSTATE[42000] [1203] User db_admin already has more than 'max_user_connections' active connections我知道最大连接数设置为15,但我已经咨询了支持,他们说我在此错误时没有连接。

在完成所有选项之后,有人可以检查我的代码以确保其中没有可能产生这些错误的错误吗?

class MyPDO extends PDO{

    const DB_HOST='localhost';
    const DB_PORT='3306';
    const DB_NAME='db_name';
    const DB_USER='db_admin';
    const DB_PASS='SECRET';

    public function __construct(){

        parent::__construct('mysql:host='.MyPDO::DB_HOST.';port='.MyPDO::DB_PORT.';dbname='.MyPDO::DB_NAME,
                            MyPDO::DB_USER,MyPDO::DB_PASS);
        try{
                $this->db = new MyPDO();
                $this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
            }catch(PDOException $e){
                //always catching the connection errors
                echo 'Connection failed: ' . $e->getMessage();
            }
    }

    public function query($query){ 
        $args = func_get_args();
        array_shift($args); 
        //check inputs
        var_dump($args);
        $reponse = parent::prepare($query);
        $reponse->execute($args);
        return $reponse;    
    }  
}

这是插入查询

function InsertUserToSql()
    {
        $ret = $this->db->query("INSERT INTO CD_USERS (email,username,password,fname,lname,dob,gender) VALUES 
        (?,?,?,?,?,?,?)",$this->Email,$this->Username,$this->Password,$this->Fname,
        $this->Lname,$this->Birthday,$this->Gender);
        if($ret){
            echo "insert success";
            return $this->db->lastInsertId();
        } 
        $this->db = null;
    }  

2 个答案:

答案 0 :(得分:0)

您有递归代码:实例在$this->db中创建一个新实例,该实例在 $this->db中创建一个新实例,该实例又创建另一个实例,等等。直到最深的一个抛出一个错误(或者你超越了PHP中的最大嵌套深度(不是在vannilla中,但是一些模块(Zend,xdebug)设置了一个限制),以先到者为准),你留下了最大N成功的实例,你可能只使用你的代码判断的第二个实例(如果MyPDO extends PDO,你可以只调用$this->query()->db中不需要另一个实例,并使用$this->db->query()

答案 1 :(得分:0)

不要扩展PDO,实际上,永远不会扩展您不拥有的对象。扩展PDO对于那些最终会使用您的代码的人来说很烦人,这是完全没有意义的(您正在尝试做什么?改进清晰且众所周知的PDO API?或者创建一个符合您当前需求的对象更好 - 这意味着:创建一个你将无法再次使用的对象,这会破坏OOP的意义)? I've been over quite a few reasons why you shouldn't extend from PDO here,值得一看。

你的实际问题:

不要在自己的构造函数中创建类的新实例!

MyPDO构造函数中创建新MyPDO将再次调用MyPDO构造函数,这将创建MyPDO的新实例,该实例将调用{{1}再次构造函数,它将创建一个MyPDO的新实例,它将再次调用MyPDO构造函数,这将... 这是工作中的无限递归。

想想这样:如果有人告诉你这个:

“如果你的右脚在左前方移动,你必须再次将你的右脚移到左脚前面”
然后,带有行走固定装置的那个虐待狂的坚果箱会指示你(在枪口下):
“现在将你的右脚放在你的左前方”
在你做 Grand ecart (或分裂)之前需要多长时间才能完成,而且不能再继续了。这就是您的代码中发生的事情。

稍微偏离主题,如果遇到问题,并尝试用PHP中的单例解决它,那么你会引入一个新问题......