首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何减少PHPUnit和ZF3测试中数据库连接的数量?

如何减少PHPUnit和ZF3测试中数据库连接的数量?
EN

Stack Overflow用户
提问于 2018-03-20 23:39:48
回答 2查看 0关注 0票数 0

我正在为Zend Framework 3应用程序编写集成/数据库测试

  • zendframework / zend-test 3.1.0
  • phpunit / phpunit 6.2.2
  • PHPUnit的/ DbUnit的 3.0.0

我的测试因失败而失败

代码语言:javascript
复制
Connect Error: SQLSTATE[HY000] [1040] Too many connections

我设置了一些断点并查看了数据库:

代码语言:javascript
复制
SHOW STATUS WHERE `variable_name` = 'Threads_connected';

我已经看到了100打开的连接。

我已经通过在以下方面断开连接来减少它们tearDown()

代码语言:javascript
复制
protected function tearDown()
{
    parent::tearDown();
    if ($this->dbAdapter && $this->dbAdapter instanceof Adapter) {
        $this->dbAdapter->getDriver()->getConnection()->disconnect();
    }
}

但我仍然80打开了连接。

如何将测试中的数据库连接数量减少到可能的最小值?

EN

Stack Overflow用户

发布于 2018-03-21 09:29:16

你可能已将PHP / DB配置为使用持久连接。只有在测试结束执行后,这些连接才会保留在那里。它没有那么坏。

从手册:永久连接是脚本执行结束时不会关闭的链接。当请求一个持久连接时,PHP会检查是否已经有一个相同的持久连接(它从前面保持打开状态) - 如果存在,它会使用它。

一旦你username@host:port建立了连接,完成了你的工作并断开连接(scipt结束执行),然后再次连接username@host:port,无论使用哪个表,你都将通过相同的连接套接字进行连接。

你的问题的四个可能的原因

  1. 因为你正在运行不同的用户来连接到数据库服务器
  2. 因为你要将表名连接起来
  3. 因为你一次运行多个测试
  4. 因为你正在建立多个连接

最有可能的是第4层,因为它试图创建一个frabric函数来创建数据库句柄,每次你需要数据库时,就是创建新的连接:

代码语言:javascript
复制
function getConnection() {
    // This is an example to test, that it do leave behind a non closed connection. 
    // Skip "p:", to reduce connections left unless you are configured
    // globally for persistency, eg. by mysqlnd.
    //                      p: forced persistency
    $link = mysqli_connect("p:127.0.0.1", "my_user", "my_password", "my_db");

    if (!$link) return false;

    return $link;
}

情况是,对于同一个线程中每个实例方法的调用,都会打开一个全新的连接,因为你真的在问这个问题。只有在不再使用持久套接字时,持久套接字才会被重用(创建者脚本先前已结束其执行)。(至少这是几年前我学会使用它们的方式)

为避免创建太多连接,重建连接工厂以存储所有不同的连接,并按需提供所需的链接,而无需一次又一次地调用连接构建器。这种方式对于一个特定的用户来说是一个终极服务器,例如你最终会运行一次。mysqli_connect从服务器检索持久连接,并在脚本执行结束时保持全部重用。

代码语言:javascript
复制
class  db
{

    static $storage = array();

    public static function getConnection($username = 'username') {

        if (!array_key_exists($username, self::$storage) {
            $link = mysqli_connect("p:127.0.0.1", $username, "my_password", "my_db");

            if (!$link) return false;

            self::$storage[$username] = $link;
        }

        return self::$storage[$username];
    }
}

// ---
$a = db::getConnection();
$b = db::getConnection();

// both $a and $b are the same connection, using the same socket on your server
var_dump($a, $b);

回到你提供的例子,这可能是因为一行:

代码语言:javascript
复制
$sql = new Sql($this->dbAdapter);

在测试中一遍又一遍地执行反复执行,或者由于驱动程序本身在经常重复使用时做了非凡的事情。我的问题是,如果驱动程序在每次getConnection()运行时都没有创建新连接,或者Sql()每次调用时都没有创建新连接的构造函数new Sql

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100007696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档