Check for gone-away database server and reconnect
Should stop the worker process crashing if mysql closes the connection due to timeout.
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
class SihnonFramework_Database {
|
class SihnonFramework_Database {
|
||||||
|
|
||||||
|
const SQLSTATE_SERVER_GONE = 'HY000';
|
||||||
|
|
||||||
private $config;
|
private $config;
|
||||||
private $dbh;
|
private $dbh;
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ class SihnonFramework_Database {
|
|||||||
$this->dbname = $this->getDatabaseConfig('dbname');
|
$this->dbname = $this->getDatabaseConfig('dbname');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->dbh = new PDO("mysql:host={$this->hostname};dbname={$this->dbname}", $this->username, $this->password);
|
$this->dbh = new PDO("mysql:host={$this->hostname};dbname={$this->dbname}", $this->username, $this->password, array(PDO::ATTR_PERSISTENT => true));
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
throw new Sihnon_Exception_DatabaseConnectFailed($e->getMessage());
|
throw new Sihnon_Exception_DatabaseConnectFailed($e->getMessage());
|
||||||
}
|
}
|
||||||
@@ -42,6 +44,16 @@ class SihnonFramework_Database {
|
|||||||
$this->dbh = null;
|
$this->dbh = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function reconnect() {
|
||||||
|
$this->dbh = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->dbh = new PDO("mysql:host={$this->hostname};dbname={$this->dbname}", $this->username, $this->password, array(PDO::ATTR_PERSISTENT => true));
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
throw new Sihnon_Exception_DatabaseConnectFailed($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the named item from the database configuration file
|
* Returns the value of the named item from the database configuration file
|
||||||
*
|
*
|
||||||
@@ -55,10 +67,27 @@ class SihnonFramework_Database {
|
|||||||
return $this->database_config[$key];
|
return $this->database_config[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function query($sql, $count = 0) {
|
||||||
|
$results = $this->dbh->query($sql);
|
||||||
|
if (! $results) {
|
||||||
|
list($std_code, $driver_code, $message) = $this->dbh->errorInfo();
|
||||||
|
|
||||||
|
if ($count == 0 && $std_code == static::SQLSTATE_SERVER_GONE) {
|
||||||
|
// Retry the query before failing
|
||||||
|
return $this->query($sql, ++$count);
|
||||||
|
} else {
|
||||||
|
throw new Sihnon_Exception_DatabaseQueryFailed($message, $driver_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function selectAssoc($sql, $key_col, $value_cols) {
|
public function selectAssoc($sql, $key_col, $value_cols) {
|
||||||
$results = array();
|
$results = array();
|
||||||
|
|
||||||
foreach ($this->dbh->query($sql) as $row) {
|
foreach ($this->query($sql) as $row) {
|
||||||
if (is_array($value_cols)) {
|
if (is_array($value_cols)) {
|
||||||
$values = array();
|
$values = array();
|
||||||
foreach ($value_cols as $value_col) {
|
foreach ($value_cols as $value_col) {
|
||||||
@@ -74,7 +103,7 @@ class SihnonFramework_Database {
|
|||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function selectList($sql, $bind_params = null) {
|
public function selectList($sql, $bind_params = null, $count = 0) {
|
||||||
if ($bind_params) {
|
if ($bind_params) {
|
||||||
$stmt = $this->dbh->prepare($sql);
|
$stmt = $this->dbh->prepare($sql);
|
||||||
|
|
||||||
@@ -84,8 +113,14 @@ class SihnonFramework_Database {
|
|||||||
|
|
||||||
$result = $stmt->execute();
|
$result = $stmt->execute();
|
||||||
if (! $result) {
|
if (! $result) {
|
||||||
list($dummy, $code, $message) = $stmt->errorInfo();
|
list($std_code, $driver_code, $message) = $stmt->errorInfo();
|
||||||
throw new Sihnon_Exception_DatabaseQueryFailed($message, $code);
|
|
||||||
|
if ($count == 0 && $std_code == static::SQLSTATE_SERVER_GONE) {
|
||||||
|
$this->reconnect();
|
||||||
|
return $this->insert($sql, $bind_params, ++$count);
|
||||||
|
} else {
|
||||||
|
throw new Sihnon_Exception_DatabaseQueryFailed($message, $driver_code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $stmt->fetchAll();
|
return $stmt->fetchAll();
|
||||||
@@ -93,7 +128,7 @@ class SihnonFramework_Database {
|
|||||||
} else {
|
} else {
|
||||||
$results = array();
|
$results = array();
|
||||||
|
|
||||||
$result = $this->dbh->query($sql);
|
$result = $this->query($sql);
|
||||||
foreach ($result as $row) {
|
foreach ($result as $row) {
|
||||||
$results[] = $row;
|
$results[] = $row;
|
||||||
}
|
}
|
||||||
@@ -111,7 +146,7 @@ class SihnonFramework_Database {
|
|||||||
return $rows[0];
|
return $rows[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function insert($sql, $bind_params = null) {
|
public function insert($sql, $bind_params = null, $count = 0) {
|
||||||
$stmt = $this->dbh->prepare($sql);
|
$stmt = $this->dbh->prepare($sql);
|
||||||
|
|
||||||
if ($bind_params) {
|
if ($bind_params) {
|
||||||
@@ -126,12 +161,19 @@ class SihnonFramework_Database {
|
|||||||
|
|
||||||
$result = $stmt->execute();
|
$result = $stmt->execute();
|
||||||
if (! $result) {
|
if (! $result) {
|
||||||
list($code, $dummy, $message) = $stmt->errorInfo();
|
list($std_code, $driver_code, $message) = $stmt->errorInfo();
|
||||||
throw new Sihnon_Exception_DatabaseQueryFailed($message, $code);
|
|
||||||
|
if ($count == 0 && $std_code == static::SQLSTATE_SERVER_GONE) {
|
||||||
|
$this->reconnect();
|
||||||
|
return $this->insert($sql, $bind_params, ++$count);
|
||||||
|
} else {
|
||||||
|
var_dump($std_code, $driver_code, $message);
|
||||||
|
throw new Sihnon_Exception_DatabaseQueryFailed($message, $driver_code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update($sql, $bind_params = null) {
|
public function update($sql, $bind_params = null, $count = 0) {
|
||||||
$stmt = $this->dbh->prepare($sql);
|
$stmt = $this->dbh->prepare($sql);
|
||||||
|
|
||||||
if ($bind_params) {
|
if ($bind_params) {
|
||||||
@@ -146,8 +188,14 @@ class SihnonFramework_Database {
|
|||||||
|
|
||||||
$result = $stmt->execute();
|
$result = $stmt->execute();
|
||||||
if (! $result) {
|
if (! $result) {
|
||||||
list($code, $dummy, $message) = $stmt->errorInfo();
|
list($std_code, $driver_code, $message) = $stmt->errorInfo();
|
||||||
throw new Sihnon_Exception_DatabaseQueryFailed($message, $code);
|
|
||||||
|
if ($count == 0 && $std_code == static::SQLSTATE_SERVER_GONE) {
|
||||||
|
$this->reconnect();
|
||||||
|
return $this->update($sql, $bind_params, ++$count);
|
||||||
|
} else {
|
||||||
|
throw new Sihnon_Exception_DatabaseQueryFailed($message, $driver_code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user