一个php脚本执行中实例多次PDO,会建立多次数据库连接。

脚本代码:

<?php

try {

    $dbh = new PDO(‘mysql:host=localhost;dbname=test‘, ‘root‘, ‘root‘);

} catch (PDOException $e) {

    exit(‘连接数据库失败1‘);

} finally {

    echo "连接成功1\n";

}

try {

    $conn = new PDO(‘mysql:host=localhost;dbname=test‘, ‘root‘, ‘root‘);

} catch (PDOException $e) {

    exit(‘连接数据库失败2‘);

} finally {

    echo "连接成功2\n";

}

try {

    $pdo = new PDO(‘mysql:host=localhost;dbname=test‘, ‘root‘, ‘root‘);

} catch (PDOException $e) {

    exit(‘连接数据库失败3‘);

} finally {

    echo "连接成功3\n";

}

echo "保持连接中...\n";
sleep(10);
echo "执行结束\n";

CLI执行:

[email protected]:/home/www/wenda/webroot# php index.php
连接成功1
连接成功2
连接成功3
保持连接中...
执行结束

在脚本sleep过程中,查看mysql的连接信息:

mysql> show processlist;
+----+------+-----------+------+---------+------+----------+------------------+
| Id | User | Host      | db   | Command | Time | State    | Info             |
+----+------+-----------+------+---------+------+----------+------------------+
|  3 | root | localhost | NULL | Query   |    0 | starting | show processlist |
| 24 | root | localhost | test | Sleep   |    6 |          | NULL             |
| 25 | root | localhost | test | Sleep   |    6 |          | NULL             |
| 26 | root | localhost | test | Sleep   |    6 |          | NULL             |
+----+------+-----------+------+---------+------+----------+------------------+
4 rows in set (0.00 sec)

可以看到一个脚本的执行产生了三个数据库连接,但是如果将后面的实例化的pdo实例赋值给之前实例化的pdo实例,则新的连接会替换掉前一个连接,而不会产生新的连接。所以我们在编程过程中,应该避免多次实例化pdo,而产生不必要的数据库性能消耗。

解决方案:

1. 封装一个单例模式的类,该类实例化的过程就是创建pdo连接的过程。我们要建立数据库连接时,不是手动实例化pdo,而是去获取这个类的实例。

2. 实例化pdo类时,设定 持久连接 参数:

  

<?php
$dbh = new PDO(‘mysql:host=localhost;dbname=test‘, $user, $pass, array(
    PDO::ATTR_PERSISTENT => true
));
?>

官方文档的引用:

很多 web 应用程序通过使用到数据库服务的持久连接获得好处。持久连接在脚本结束后不会被关闭,且被缓存,当另一个使用相同凭证的脚本连接请求时被重用。持久连接缓存可以避免每次脚本需要与数据库回话时建立一个新连接的开销,从而让 web 应用程序更快。

  1. 官方所说的脚本结束,在fpm模式下就是指一次客户端请求的结束另一个使用相同凭证的脚本也就可以对应成另一个使用相同数据库连接凭证的客户端请求。首先我们要知道,这两次客户端的请求是根据fpm-workers的空闲情况,被分配给某个worker去执行的,所以两次请求被分配到同一个worker的可能性很低。接着,我们阐明下面的情景。
  2. 2. 开启持久连接之后,数据库连接是被缓存于fpm进程之中的。如果某个fpm-worker进程中已经缓存了持久连接,此时可能出现如下两种情况:

    • 当脚本中再次执行带 ATTR_PERSISTENT 参数的pdo连接时,会复用之前的连接,而不会产生新的连接。
    • 当脚本中再次执行不带 ATTR_PERSISTENT 参数的pdo连接时,还会再次产生一个新的数据库连接。

原文地址:https://www.cnblogs.com/xingyazhao/p/8569496.html

时间: 2024-10-25 08:27:06

一个php脚本执行中实例多次PDO,会建立多次数据库连接。的相关文章

history 查看历史操作记录在shell脚本执行中无法显示问题

今天使用shell脚本想查看历史操作命令的记录于是写了一个再简单不过的脚本,可是以chmod +x 权限执行./test.sh发现执行后没有任何反应.于是查找原因:将脚本文件中的#!/bin/bash去掉后可以正确执行

反思一个软件项目执行中的问题

近期参与了一个联网管理平台的软件项目,该项目由2017年8月立项,迄今已经大半年了.从项目进展上,暴露出一些问题: 1. 项目进度被一拖再拖,原定2018年春节前完成一期功能的上线并完成相关实验局的部署,但目前已经4月份一期功能还未完全完成. 2. 项目质量问题很多.该项目分为前端和后端平台两套系统,这两套系统的协同工作出现很多问题,直至现在,一些基本的功能还老出问题. 3. 项目管理流程混乱,一个问题出现经常找不到干系人,没有统一的协调和控制,解决问题的效率很低. 对该项目出现的问题做了一些反

shell脚本中执行另一个shell脚本

分类: 可以在一个shell脚本中执行另一个shell脚本(或非可执行文件,主要用于取得一些变量的值),方法是: . 文件名(包括路径) 或 变量=文件名(包括路径) . $变量 注意,圆点后面有个空格. 这样,在本shell脚本的后面部分就可以引用其他文件中声明的一些变量. 当再用这些变量去执行第3个脚本时,我不知是怎么回事,总是有些莫名其妙的错误,发现只有这个文件中不存在空行才行,哪怕只有一个注释符,都不会出错,就是不能有空行. 其实我想应该也不是这个问题,而是windows和linux处理

在bat脚本中执行另一个bat脚本,下面的命令不再执行

在bat脚本中执行另一个bat脚本,下面的命令不再执行,如下bat.bat: bat1.bat bat2.bat 在执行完bat1.bat 之后直接返回,bat2.bat没有被执行,这种情况下,用call bat1.bat即可解决,如下: call bat1.bat call bat2.bat 至于是什么原因也没有去分析,毕竟bat脚本很少写,能用就好.

mysql中如何在命令行中,执行一个SQL脚本文件?

需求描述: 在mysql数据库的使用中,有的时候,需要直接在shell的命令行中,执行某个SQL脚本文件, 比如,要初始化数据库,创建特定的存储过程,创建表等操作,这里进行一个基本的测试. 一般情况,mysql都是以交互式的方式登录,执行SQL语句的.这里要做的就是将SQL放在一个文件里,让mysql 客户端程序来执行. 操作过程: 1.创建一个SQL脚本的文本文件,里面放想要执行的SQL语句 use test01 select count(*) from ts051; 备注:SQL脚本的文件名

shell脚本中判断上一个命令是否执行成功

2018-12-21 shell中使用符号"$?"来显示上一条命令执行的返回值,如果为0则代表执行成功,其他表示失败.结合if-else语句实现判断上一个命令是否执行成功 示例如下: if [ $? -ne 0 ]; then echo "failed" else echo "succeed" fi 或者: if [ $? -eq 0 ]; then echo "succeed" else echo "failed&

转:Shell 编程--本文结合大量实例阐述如何编写一个shell脚本

转自:情報官世界 本文结合大量实例阐述如何编写一个shell脚本. 为什么要进行shell编程 在Linux系统中,虽然有各种各样的图形化接口工具,但是sell仍然是一个非常灵活的工具.Shell不仅仅是命令的收集,而且是一门非常棒的编程语言.您可以通过使用shell使大量的任务自动化,shell特别擅长系统管理任务,尤其适合那些易用性.可维护性和便携性比效率更重要的任务. 下面,让我们一起来看看shell是如何工作的: 建立一个脚本 Linux中有好多中不同的shell,但是通常我们使用bas

crontab 中 python(cx_Oracle)脚本执行时需要用户环境变量,怎么办??

import cx_Oracle Traceback (most recent call last): File "", line 1, in ? ImportError: libclntsh.so.10.1: cannot open shared object file: No such file or directory 看以下帖子解决的,唯一比他幸运的是看了他的贴子,不用花半天~:) ~~~~~~~~~~~~ crontab 中 python 脚本执行失败的解决方法 写服务器程序

Linux中两种脚本执行方式的区别:. xx 和 ./xx

今天继续在看Building Linux Embedded Systems一书,进入第四章,有一些实际的操作,其中在介绍了良好的组织架构(文件夹)后,建议些一个script可以进行不同的开发环境.里面很简单,包括一个export和cd的命令,这个脚本假设为 export PROJECT=/home/aaa/project1 cd $PROJECT 并取名字为 test 我执行$ ./test,发现没有效果,然后在里面增加两个跟踪语句,如下 export PROJECT=/home/aaa/pro