首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FreeTDS:正确关闭PDO连接,不能正常工作

问FreeTDS:正确关闭PDO连接,不能正常工作
EN

Stack Overflow用户
提问于 2014-08-12 14:34:25
回答 2查看 1.3K关注 0票数 0

我有一个旧的CodeIgniter实例,我正试图在PDO中使用它。这是基于"cickes“的修改(见下面的链接)。它在小请求负载下工作良好,但在重请求负载下连接似乎挂起了很长一段时间。最后,我用完了可用的连接,DB返回和错误: SQLSTATEnull (严重性0)。

https://github.com/cickes/PDOinCodeigniter2

我使用的是带有PDO的2008。MSSQL的是FreeTDS驱动程序,可以在phpinfo()输出中看到。FreeTDS PHPINFO如下所示:

代码语言:javascript
复制
mssql
MSSQL Support   enabled
Active Persistent Links 1
Active Links    1
Library version FreeTDS
Directive   Local Value Master Value
mssql.allow_persistent  On  On
mssql.batchsize 0   0
mssql.charset   no value    no value
mssql.compatability_mode    Off Off
mssql.connect_timeout   5   5
mssql.datetimeconvert   On  On
mssql.max_links Unlimited   Unlimited
mssql.max_persistent    Unlimited   Unlimited
mssql.max_procs Unlimited   Unlimited
mssql.min_error_severity    10  10
mssql.min_message_severity  10  10
mssql.secure_connection Off Off
mssql.textlimit Server default  Server default
mssql.textsize  Server default  Server default
mssql.timeout   60  60

我已经将DB处理程序设置为null,以及unset() -- DB处理程序。这两种改变都没有帮助。最终我失去了联系。

我认为我可以尝试在连接期间传递一个属性选项,就像PHP网站上建议的那样。不幸的是,FreeTDS驱动程序不支持属性。第一个定义的$DB正在工作,但我相信它使用的是持久连接。

代码语言:javascript
复制
$DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password']);

注意:驱动程序不支持下面的属性设置示例。

代码语言:javascript
复制
$DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password'], array(
    PDO::ATTR_PERSISTENT => false
));

消息: PDO::__construct():SQLSTATEIM001: Driver不支持此函数: driver不支持设置属性

新的PDO($params'dbdriver'.':host='.$params'hostname'.';dbname=‘.$params’数据库‘,$params’用户名‘,$params’密码‘);

PDO::__construct():SQLSTATEIM001: Driver不支持此函数: driver不支持设置属性。

也许是持久的链接导致了这个问题?我认为这个服务器上也使用了一些非持久性的mssql_connect()函数。也许有人可以为FreeTDS驱动程序提出更好的配置建议?

Laravel测试(添加于2014年8月14日):

我决定用相同的数据库连接设置在“同一台服务器”上测试Laravel。它不会产生同样的问题。我可以连续多次点击它,而不会出现“挂起”或DB错误。因此,这就引出了一个问题: Laravel是如何以不同的方式执行PHP的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-14 14:04:41

CodeIgniter的Cickles更改包含了我发现的一个bug。DB函数被多次调用,因此数据库连接被多次调用(9)。为了防止这种情况,我首先检查对全局DB变量的引用,以确保没有创建到数据库的另一个连接。我希望这个答案能帮助其他可能经历同样问题的人。

见Github项目:

https://github.com/cickes/PDOinCodeigniter2

文件:

https://github.com/cickes/PDOinCodeigniter2/blob/master/system/database/DB.php

代码语言:javascript
复制
if (!empty($GLOBALS['DB'])) $DB = $GLOBALS['DB'];
//var_dump($DB);
//echo "DB Function Called."."<br />";

if (empty($DB)) {

// Using PDO: connect to a database using PDO
try {

    echo "Creating new PDO Connection!";
    $DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password']);

    if (ENVIRONMENT == 'development') {
        $DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } elseif (ENVIRONMENT == 'production') {
        $DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    }
    $DB->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
    $DB->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);
    $DB->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
    //$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    $GLOBALS['DB'] = $DB;

} catch(PDOException $e) {

    //print_r($params);
    echo $e->getMessage();
}

}
票数 1
EN

Stack Overflow用户

发布于 2014-08-12 20:12:42

如果可能的话,尝试重用连接,不要自己关闭它们(PDO足够聪明地做到这一点)。

在创建新连接之前检查连接是否为null

代码语言:javascript
复制
if($DB == null){
    $DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password']);
    $DB->setAttribute(PDO::ATTR_PERSISTENT, false);    
}

否则,重用相同的对象。

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

https://stackoverflow.com/questions/25267059

复制
相关文章

相似问题

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