我有一个旧的CodeIgniter实例,我正在尝试使用PHP PDO。这是基于“cickes”修改(见下面的链接)。它在小的请求负载下运行良好,但是在大量请求负载下连接似乎会挂起很长时间。最终我用完了可用的连接,数据库返回并出错:SQLSTATE [](null)(严重性为0)。
https://github.com/cickes/PDOinCodeigniter2
我正在使用带有PHP PDO的MS SQL Server 2008。 MSSQL的PHP驱动程序是FreeTDS驱动程序,可以通过phpinfo()输出看到。 FreeTDS PHPINFO如下所示:
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
我已将数据库处理程序设置为null以及取消设置()数据库处理程序。两种变化都无济于事。最终我用完了。
我认为我可以尝试在连接期间传递属性选项,如PHP网站上所建议的那样。不幸的是,FreeTDS驱动程序不支持属性。第一个定义的$ DB正在运行,但我相信它使用持久连接。
$DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password']);
注意:驱动程序不支持下面的属性设置示例。
$DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password'], array(
PDO::ATTR_PERSISTENT => false
));
消息:PDO :: __ construct():SQLSTATE [IM001]:驱动程序不支持此功能:驱动程序不支持设置属性
$ DB = new PDO($ params ['dbdriver']。':host ='。$ params ['hostname']。'; dbname ='。$ params ['database'],$ params ['username '],$ params ['密码']);
PDO :: __ construct():SQLSTATE [IM001]:驱动程序不支持此功能:驱动程序不支持设置属性。
也许持久链接导致问题?我认为此服务器上也使用了非持久性mssql_connect()函数。也许有人可以为FreeTDS驱动程序建议更好的配置?
Laravel测试(2014年8月14日添加):
我决定使用相同的数据库连接设置在“同一台服务器”上测试Laravel。它不会产生同样的问题。我可以连续多次击中它而不会出现“挂起”或DB错误。因此,这提出了一个问题:Laravel如何以不同的方式进行PHP PDO?
答案 0 :(得分:1)
CodeIgniter的Cickles PDO更改包含我发现的错误。 DB函数被多次调用,因此多次调用数据库连接(9)。为了防止这种情况,我首先检查对全局数据库变量的引用,以确保我没有创建与数据库的另一个连接。我希望这个答案可以帮助其他可能遇到同样问题的人。
参见Github项目:
https://github.com/cickes/PDOinCodeigniter2
文件:
https://github.com/cickes/PDOinCodeigniter2/blob/master/system/database/DB.php
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 :(得分:0)
如果可能的话尝试重用连接,不要自己关闭它们(PDO足够智能)。
在创建新连接之前检查连接是否为null
if($DB == null){
$DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password']);
$DB->setAttribute(PDO::ATTR_PERSISTENT, false);
}
否则重复使用同一个对象。