博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP连接MySql闪断自动重连的方法
阅读量:6347 次
发布时间:2019-06-22

本文共 3456 字,大约阅读时间需要 11 分钟。

  hot3.png

使用php作为后台运行程序(例如短信群发),在cli模式下执行php,php需要连接mysql循环执行数据库处理。

当mysql连接闪断时,之后循环的执行将会失败。

我们需要设计一个方法,当mysql闪断时,可以自动重新连接,使后面的程序可以正常执行下去。

1.创建测试数据表

CREATE TABLE `user` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(20) NOT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.插入测试数据

insert into user(name) values('fdipzone'),('xfdipzone'),('terry');mysql> select * from user;+----+-----------+| id | name |+----+-----------+| 1 | fdipzone || 2 | xfdipzone || 3 | terry |+----+-----------+

3.后台运行的php文件

db.php

PDO::ERRMODE_EXCEPTION,);if ($charset != '') {$h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼}if ($pconnect) {$h_param[PDO::ATTR_PERSISTENT] = true;}$conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);} catch (PDOException $e) {throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);}self::$_instance = $conn;return $conn;}// 执行查询public static function query($dbconn, $sqlstr, $condparam){$sth = $dbconn->prepare($sqlstr);try{$sth->execute($condparam);} catch (PDOException $e) {echo $e->getMessage().PHP_EOL;}$result = $sth->fetchAll(PDO::FETCH_ASSOC);return $result;}}?>

test.php

'localhost','dbname' => 'user','user' => 'root','password' => '','pconnect' => 0,'charset' => '');// 循环执行while(true){// 创建数据连接$dbconn = DB::get_conn($config);// 执行查询$sqlstr = 'select * from user where id=?';$condparam = array(mt_rand(1,3));$data = DB::query($dbconn, $sqlstr, $condparam);print_r($data);// 延时10秒echo 'sleep 10'.PHP_EOL.PHP_EOL;sleep(10);}?>

4.执行步骤

在php cli模式下执行test.php,然后马上执行mysql.server stop 与 mysql.server start 模拟闪断

mysql.server stopShutting down MySQL.. SUCCESS!mysql.server startStarting MySQLSUCCESS!

可以看到,闪断后不能重新连接数据库,后面的程序不能执行下去。

Array([0] => Array([id] => 3[name] => terry))sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone awayArray()sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone awayArray()sleep 10...

5.增加重连机制

if(isset(self::$_instance) && !empty(self::$_instance)){return self::$_instance;}

闪断后,因为 self::$_instance 的值存在,因此调用get_conn并不会重新连接,而是使用保存的连接进行处理。

这样实际上是当连接存在时,不需要再次创建mysql连接,减少mysql连接数。

所以需要在闪断后,清空self::$_instance的值,使下次重新获取连接,而不使用已经创建但失效的数据库连接。

改进方法如下:

增加reset_connect方法,当出现错误时调用。如果判断错误是MySQL server has gone away则清空已经存在的数据库连接,清空后下次则会重新连接mysql。

修改后的php文件如下:

db.php

PDO::ERRMODE_EXCEPTION,);if ($charset != '') {$h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼}if ($pconnect) {$h_param[PDO::ATTR_PERSISTENT] = true;}$conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);} catch (PDOException $e) {throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);}self::$_instance = $conn;return $conn;}// 执行查询public static function query($dbconn, $sqlstr, $condparam){$sth = $dbconn->prepare($sqlstr);try{$sth->execute($condparam);} catch (PDOException $e) {echo $e->getMessage().PHP_EOL;self::reset_connect($e->getMessage()); // 出错时调用重置连接}$result = $sth->fetchAll(PDO::FETCH_ASSOC);return $result;}// 重置连接public static function reset_connect($err_msg){if(strpos($err_msg, 'MySQL server has gone away')!==false){self::$_instance = null;}}}?>

6.再次进行闪断执行

可以看到改进后的效果,闪断后,当前执行的会失败,但之后的可以重新创建新连接继续执行下去。

Array([0] => Array([id] => 2[name] => xfdipzone))sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone awayArray()sleep 10Array([0] => Array([id] => 1[name] => fdipzone))sleep 10...

文章同步发布: 

转载于:https://my.oschina.net/os2015/blog/2874554

你可能感兴趣的文章
《淘宝店铺设计装修一册通》一导读
查看>>
Qt之处理QNetworkAccessManager网络连接超时
查看>>
YunOS场景文字识别
查看>>
OpenSSL "heartbleed" 的安全漏洞
查看>>
Windows 10 Build 14366 面向 Slow 通道开放
查看>>
国内虚拟主机好还是国外虚拟主机对SEO更有利
查看>>
《程序员的修炼——从优秀到卓越》一一1.2 今天上班可以放羊
查看>>
美国男女程序员的薪水相差不大
查看>>
Resty 1.2.0-SNAPSHOT 更新,可通过header来控制api的版本,数据源读写分离
查看>>
为什么 JavaScript 会在移动端中胜出?
查看>>
《编写高质量代码:改善c程序代码的125个建议》——建议4:数据类型转换必须做范围检查...
查看>>
现实生活中的 Linux
查看>>
Spring整合Mongodb,Maven的依赖,Spring配置,MongoDB的公共操作类,使用SpringMVC的Controller进行测试并返回结果的案例...
查看>>
《LoadRunner性能测试巧匠训练营》——1.6 本章小结
查看>>
《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.9 总结
查看>>
哪个对象才是锁?
查看>>
《乐高EV3机器人搭建与编程》一1.4 特殊的部件
查看>>
《Oracle性能优化与诊断案例精选》——1.5 云和恩墨,数据服务起征途
查看>>
《Arduino家居安全系统构建实战》——1.4 那么,如何知道程序有效?
查看>>
《Unity 3.x游戏开发实例》——2.16节小结
查看>>