Mysql 打开第二个数据库连接时,点火钥匙锁定事务超时

Mysql 打开第二个数据库连接时,点火钥匙锁定事务超时,mysql,model-view-controller,transactions,Mysql,Model View Controller,Transactions,我遇到了一个问题,涉及一个类中的数据库事务,由于事务中打开了辅助数据库连接而超时;当我添加外键约束时,问题开始出现。以及,使用以下方法进行测试: SET foreign_key_checks = 0; 我已经证实了这一点 我的数据库类如下所示(我省略了所有的方法): 我的模型如下所示: class Model { function __construct() { $this->db = new Db(array('host'=>DB_HOST,'dbnam

我遇到了一个问题,涉及一个类中的数据库事务,由于事务中打开了辅助数据库连接而超时;当我添加外键约束时,问题开始出现。以及,使用以下方法进行测试:

SET foreign_key_checks = 0;
我已经证实了这一点

我的数据库类如下所示(我省略了所有的方法):

我的模型如下所示:

class Model {

    function __construct() {
        $this->db = new Db(array('host'=>DB_HOST,'dbname'=>DB_NAME,'username'=>DB_USERNAME,'password'=>DB_PASSWORD));
    }

}
下面的代码执行一点逻辑,然后插入到question_orders表中:question_orders有一个列question_id,带有一个外键索引,它引用父表questions;我认为问题在于评估问题顺序扩展了模型并创建了一个新的数据库连接?如果您对如何维护交易和外键方面有任何想法,我们将不胜感激

  class This_Is_A_Problem extends Model() {

       public function __construct() {
             parent::construct();
           }

       public function problemFunction()  {

    /*variable init code left out*/

    $this->db->beginTransaction();
    $db_result = false;
    try {

    $db_result = $this->db->insert('questions', $questions_data);
    $new_insert_id = $this->db->lastInsertId();

    $assessment_question_orders = new Assessment_Question_Orders();

 $question_number = $assessment_question_orders->insertSingleQuestionOrder($module_id, $new_insert_id);

    $db_result = $this->db->commit();

    }
    } catch (PDOException $e) {

     $this->db->rollBack();

    }}}
一个线程(通常)应该只有一个到数据库的连接。因此,我推荐以下模式之一:

方案A:将单个$db传递到所有类:

$db = new PDO(...);
$my_obj = new My_Class($db);  -- $db is saved in $this->db for use within the methods of My_Class.
方案B:使用getter方法的单例Db类:

// Singleton (of sorts)
class Db
{
    private static $db;
    function __construct()
    {
        self::$db = new PDO(...);
        // A variant would include "lazy" instantiation of self::$Db. 
    }
    function Get_Db()  { return self::$db; } // All calls get the same `db`
}
class My_class
{
    function My_Method()
    {
        $db = Db::Get_Db();
        $db->...
    }
}

new Db();   // one time call at start of program

在一个程序中很少需要两个db连接。A计划很容易考虑到这一点。(但看看你是否能避免它——因为它,你现在有麻烦了。)

两种解决方案都非常清楚。然而,对我来说,解决方案1似乎是“更多的工作”,因为我必须在整个应用程序中将$db传递到我的所有类中。如果我采用第二种方法,那么在引导过程中调用new db()之后,我会让$this->db=db::Get_db()进入我的模型。然后,我应该在上面的代码中包含这一点(请参见编辑),如果这个问题扩展了模型,并且它的构造函数调用了parent::\uu construct(),所有调用都会得到相同的“db”,我就不会遇到以前遇到的问题。我的理解正确吗?听起来正确
Db::Get_Db()
是连接的同一个副本,不管您是在构造函数中调用它(就像您所做的)还是在方法中调用它(就像我所做的)。只需确保只调用一次
newdb()
。(对
类Db
使用“单例模式”是另一种变体。)
// Singleton (of sorts)
class Db
{
    private static $db;
    function __construct()
    {
        self::$db = new PDO(...);
        // A variant would include "lazy" instantiation of self::$Db. 
    }
    function Get_Db()  { return self::$db; } // All calls get the same `db`
}
class My_class
{
    function My_Method()
    {
        $db = Db::Get_Db();
        $db->...
    }
}

new Db();   // one time call at start of program