MySql测试中达到最大连接数

11

当我启动PHPUnit测试套件时,我达到了MySQL的最大连接限制(200)。

临时解决办法是将max_connection设置为500,但我正在寻找更好的Zend Framework 2环境下的解决方法。

我尝试添加一些tearDown方法,但似乎没有效果或者是不完整的解决方案。

这是一段代码示例:

protected function tearDown()
{
    // i have two entitymanager
    $this->getObjectManager()->get('doctrine.connection.orm_alternate')->close();
    $this->getObjectManager()->get('doctrine.connection.orm_default')->close();
    $this->application = null;
    gc_collect_cycles();
    parent::tearDown();
}

我尝试将 processIsolation 设置为 true,但一些测试太长了,以至于我认为我的控制台已经冻结了之类的。

使用 Doctrine2 连接和 Zend Framework,在 PHPunit 测试期间如何防止 "Too many connection"?

迄今为止,根据 @awons 的提示,我尝试修改 $this->getObjectManager()->get('doctrine.connection.orm_alternate')->close();

改为 $this->getObjectManager()->get('doctrine.entitymanager.orm_alternate')->close();

我检查了 teardown 是否被调用过,是的。

有些我不明白的是:每次测试都会创建一个连接的新实例,为什么这不是同一个实例?(像单例或注册表)?但即使在测试通过后没有使用它,这个实例也永远不会关闭。

我错过了什么但不知道是什么。


你尝试过关闭管理器本身吗:$this->getObjectManager()->close() - Aleksander Wons
Doctrine\DBAL\Connection - Greco Jonathan
您能获取Doctrine对象吗?类似于$this->getObjectManager()->get('doctrine')这样的代码? - Aleksander Wons
嗯,无法为Doctrine创建实例,可能别名不正确? - Greco Jonathan
你是在测试引导程序、测试中还是 setUp() 方法中设置连接/应用程序?尝试在测试执行之前创建连接。这样,你的连接就可以被重复使用了。 - nofreeusername
显示剩余10条评论
4个回答

4
我之前解决过类似的问题,是通过以下方式实现的:
protected static $my_db_for_testing

public static function setUpBeforeClass()
{
    //create your DB connection once, here.
    $self::$my_db_for_testing = new DbConnectionWhatever()
}

protected function setUp()
{
    $this->my_obj_to_test = new MyObject();
    $this->my_obj_to_test->setDb($this->my_db_for_testing);
}



public function testOne()
{
    //normal test here
}

public static function tearDownAfterClass()
{
    //close the DB connection here
}

}


致命错误:在非对象上下文中使用$this,对于beforeClass和EndClass都是如此。解决这个问题需要修改我的单元测试架构,涉及太多编码工作。目前没有时间处理这个问题。 - Greco Jonathan
有什么原因需要这样做/这样做的作用是什么?即使每个连接都在下一个单元测试运行之前使用setup()/teardown()打开、使用和关闭,我仍然遇到最大连接错误。 - Brad

3
我建议阅读关于夹具的章节。为避免每次测试都创建新的连接,请使用setUpBeforeClass()来建立一次数据库连接并在测试中重复使用该连接。
<?php
  class DatabaseTest extends PHPUnit_Framework_TestCase
  {
     protected static $dbh;

     public static function setUpBeforeClass()
     {
       self::$dbh = new PDO('sqlite::memory:');
     }

     public static function tearDownAfterClass()
     {
       self::$dbh = NULL;
     }
  }
?>

3

我们通常会配置以下设置:

set-variable = max_connections=1500

set-variable = max_user_connections=300

当连接服务器的用户少于10个时,这会为超级用户留出连接。我们的MySQL服务器通常有2-3个应用程序用户。因此,在3个用户的情况下,只能使用900个连接。如果您想进一步调整,还可以对每个用户的连接进行限制。


就像我说的那样,我尝试了将max_connections设置为1500的热修复,但是我的项目正在增长,这并没有解决问题。明年我会将这些设置调整到10,000吗?不会。 - Greco Jonathan

3

你的测试是否需要运行在MySql上?

使用Doctrine,你可以使用sqlite数据进行测试。除非有特定需求需要使用MySql,否则这种方法可以改善你的测试过程并将你与实际单元测试之外的问题隔离开来。

此外,通过在内存中对数据库进行测试,你可能会看到速度上的提升。


我的测试也是功能性的,我的项目需要数据,有时在我的测试中我需要执行真正的SQL查询,因为我们的数据库不可靠,有些测试仅用于控制数据... - Greco Jonathan
SQLite可以提供数据,并且可以使用SQL进行查询。 - Tim Klever

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接