Hjaelp mit system laver flere tusinde TCP forbindelser til min mysql database
Sorry er paa US keyboard.Jeg bruger en OOP infrastruktur til lettere at holde styr paa min kode. Problemet er den er for langsom og laver for mange tcp forbindelser til databasen.
Til hvert object anvender jeg 2 klasser fordelt i 2 filer og 1 fil hvor disse klasser og metoder bliver andvendt og en database klasse til at forbinde til databasen.
F.eks. Objektet Department vil bestor af disse 4 filer:
database.php ---> forbinder til databasen, returnere resultatet og lukker forbindelsen.
department.php ---> get og set'ere.
departmenthandler.php ---> Inkludere database.php klassen og indeholder metoder til at hente data ind og ud af databasen.
DepartmentViewer.php ---> Denne fil bruger departmenthandler.php til at hente data ud af databasen og derefter kan man formatere outputtet som man vil.
DepartmentHandler'en:
Hvis jeg henter ET ID ud af databasen via readDepartmentById($iId) laver den bare 1 forbindelse og gemmer data'en i et array og lukker forbindelsen.
Problemet er hvis jeg henter mere en 2 ID'er ud af databasen f.eks. readAllDepartments() som bruger metoden executeMultiRowQuery i filen Database.php eksekveres een SQL query som gemmer ID'erne i et array. Derefter i foreach lykken for hvert ID kalder jeg readDepartmentById($iId) som let og struktureret anvender mine getter og setter metoder i filen deaprtment.php til at danne et object array som bliver returneret. Men for hvert ID i foreach lykken bliver metoden executeSingleRowQuery i Database.php kaldt, som oabner en forbindelse, eksekvere en query og lukker forbindelsen.
Problemet er at hvis der er flere tusinde id'er bliver siden langsom og hvis jeg monitorer mine TCP forbindelser via en kommand prompt "netstat -n -a |findstr 3306" er der flere tusinde forbindelser der bliver obnet og lukket paa meget kort tid. Eftersom windows som standard kun kan ha' 5000 forbindelser korende paa samme tid, blev jeg nodt til at modificerer registrerings-databasen til nu 65000 tcp forbindelser kan kore paa samme tid.
Det virker men selvfolgelig er dette ikke optimalt og det er hovedorsagen til at jeg meget gerne vil ha hjalp til at fixe dette.
Problemet er at systemet allerede er meget stort og jeg vil helst undgaa at lave for mange rettelser. Alle klasserne er lavet paa samme moede.
Jeg hoeber der er en moede hvorpaa selve klasse structuren kan forblive den samme saa jeg ikke behoever at kalde min klasse paa en anden moede.
Jeg har haft svaert ved at forklare problemet saa jeg undskylder hvis det lyder meget forvirende. Er villig til at oppe points til een der kan give et kode eksempel paa en loesning for har virkelig brug for en loesning hurtigst muligt.
________________________________________________________________________________________________________________
****************
* database.php *
****************
class Database
{
private $sHost;
private $sUser;
private $sPassword;
private $sDatabase;
private $link;
function __construct()
{
$this->configReader();
}
// executeMultiRowQuery bruges til at returnere et two-demisionelle array
public function executeMultiRowQuery($sSql)
{
$this->openConn();
$aaResult = mysql_query($sSql);
if (!$aaResult)
{
die('<p>Invalid query: '.mysql_error()."</p>");
}
while ($aRow = mysql_fetch_array($aaResult, MYSQL_BOTH))
{
$aaEndResult[] = $aRow;
}
$iResultCount = mysql_num_rows($aaResult);
mysql_free_result($aaResult);
$this->closeConn();
if ($iResultCount > 0)
return $aaEndResult;
return null;
}
// executeSingleRowQuery bruges til at returnere et array.
public function executeSingleRowQuery($sSql)
{
$this->openConn();
$aResult = mysql_query($sSql);
if (!$aResult)
{
die('<p>Invalid query: '.mysql_error()."</p>");
}
while ($aRow = mysql_fetch_array($aResult, MYSQL_BOTH))
{
$aEndResult = $aRow;
}
$iResultCount = mysql_num_rows($aResult);
mysql_free_result($aResult);
$this->closeConn();
if ($iResultCount > 0)
return $aEndResult;
return null;
}
// executeNonQuery returnerer ikke noget, men bruges til insert, update og delete.
public function executeNonQuery($sSql)
{
$this->openConn();
$aResult = mysql_query($sSql);
if (!$aResult)
{
die('<p>Invalid query: '.mysql_error()."</p>");
}
$iAffectedRows = mysql_affected_rows($this->link);
$this->closeConn();
return $iAffectedRows;
}
// safeString bruges til at køre strengen igennem med. Det er for sikkerhedsmæssige årsager at denne bruges,
// så man ikke kan lave SQL injection attack.
public function safeString($value)
{
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
if (!is_int($value))
{
$this->openConn();
$value = "'".mysql_real_escape_string($value)."'";
$this->closeConn();
}
return $value;
}
// openConn bruges til at åbne forbindelse til databasen.
private function openConn()
{
$this->link = mysql_connect($this->sHost, $this->sUser, $this->sPassword) or die("<p>Could not connect : ".mysql_error()."</p>");
mysql_select_db($this->sDatabase) or die("<p>Could not select database</p>");
}
// closeConn lukker forbindelsen til serveren.
private function closeConn()
{
mysql_close($this->link);
}
// Læser konfigurationsfilen conf.php
private function configReader()
{
include $_SERVER["DOCUMENT_ROOT"] ."/conf.php";
$this->sHost = $sDbHost;
$this->sUser = $sDbUser;
$this->sPassword = $sDbPassword;
$this->sDatabase = $sDbDatabase;
}
}
______________________________________________________________________________________________________________________________________________________________________________________________
******************
* department.php *
******************
class Department
{
private $iDepartment_Id;
private $sDepartment_Name;
function __construct()
{
}
public function getDepartment_Id() {return $this->iDepartment_Id;}
public function setDepartment_Id($value) {$this->iDepartment_Id = $value;}
public function getDepartment_Name() {return $this->sDepartment_Name;}
public function setDepartment_Name($value) {$this->sDepartment_Name = $value;}
}
________________________________________________________________________________________________________
*************************
* DepartmentHandler.php *
*************************
include_once "classes/database.php";
include_once "classes/departments/department.php";
class DepartmentHandler
{
private $oDepartment;
private $oaDepartments;
private $oDb;
function __construct()
{
$this->oDepartment = new Department();
$this->oDb = new Database();
}
public function readDepartmentById($iId)
{
$this->oDepartment = new Department();
$sSql = "SELECT * FROM configuration_departments WHERE department_id = ".$iId."";
$aResult = $this->oDb->executeSingleRowQuery($sSql);
$this->oDepartment->setDepartment_Id($iId);
$this->oDepartment->setDepartment_Name($aResult['department_name']);
return $this->oDepartment;
}
public function readAllDepartments()
{
$this->oaDepartments=array();
$sSql = "SELECT department_id FROM configuration_departments ORDER BY department_name";
$aaDepartmentIds = $this->oDb->executeMultiRowQuery($sSql);
if($aaDepartmentIds)
{
foreach ($aaDepartmentIds as $aDepartmentId)
{
$this->oaDepartments[] = $this->readDepartmentById($aDepartmentId['department_id']);
}
}
return $this->oaDepartments;
}
}
_____________________________________________________________________________________________________________________________________________________________
************************
* DepartmentViewer.php *
************************
include_once "classes/departments/departmenthandler.php";
print "<table border='1'><tr><td><b>Department</b></td><td><b>Email Address</b></td></tr>";
$DepartmentHandler = new DepartmentHandler();
foreach($DepartmentHandler->readAllDepartments() as $value)
{
print "<tr><td>".$value->getDepartment_Name()."</td></tr>";
}
print "</table>";
_______________________________________________________________________________________________________________