soooldier
(Soooldier)
January 4, 2013, 9:22am
1
首先感谢qiang给我们共享了一个这么受用的web框架。
在使用yii的过程中,我遇到了一个问题,大致概述如下:
$user_list = fetch_user_from_db();
foreach($user_list as $user)
{
send_mail_to_user($user->id);
update_db_user_mail_status($user->id);
}
mysql wait_timeout配置10秒;
在这个crontab执行的过程中,由于send_mail_to_user调用的外部服务,它返回时间在极少数情况下会有超过10秒的情况。最终导致超过mysql wait_timeout的设置。于是在db层增加一个gone away重连的机制(CDbCommand里面的函数execute和queryInternal中增加了判断),加上以后通过CDbcommand进行的操作成功进行了重连,但是通过activerecord进行的操作还是无效。由于对框架的理解还不是特别深入,所以不知道把这个机制加到什么地方比较好。
soooldier
(Soooldier)
January 6, 2013, 2:48am
2
问题解决了,如有需要的同学可以做一个参考;修改db\CDbConnection.php文件(420行开始):
public function getPdoInstance()
{
$report_level = error_reporting(0);
// 如果由于延时操作php与mysql的连接时间操作wait_timeout(10秒),那么数据库重新连接
try {
if($this->getServerInfo() === 'MySQL server has gone away')
{
$this->_pdo = null;
$this->open();
}
} catch(Exception $e) {
if(strpos($e->getMessage(), 'gone away') !== false)
{
$this->_pdo = null;
$this->open();
}
}
error_reporting($report_level);
unset($report_level);
return $this->_pdo;
}
在getPdoInstance函数里增加了对连接的判断,但是在php版本5.2.x和5.3.x之间会有差异。在5.2.x里如果连接失效直接返回字符串信息"MySql server has gone away",但是在5.3.x里则是抛出异常并且报warning级别的错误 。很奇怪为什么会同时抛异常和报错,正因为这个warning错误,所以在错误控制上也增加了一个很小的改动。
darasion
(Darasion)
April 13, 2013, 5:05am
3
这个问题在开发后台 commands 的时候经常会遇到,
建议强哥考虑以下这个问题,从底层支持一下。
与其大家都直接改yii源码,或者自己写一大堆不规范的扩展,
不如将这个问题用标准稳定健壮的办法在框架内直接解决掉。