Autor Zpráva
BitaSk
Profil
Zdravím, prosím vás mám problém s max_connections ... Při testování nových funkcí, jednou za čas my vyskočí chyba. Mysql max connections, to jsem doposud řešil tím, že jsem v configu mysql zvýšil limit počtu připojení, ale to se mi zdá, jako špatné řešení. Nyní jsem už na hodnotě 500. Jak bych měl tento problém řešit ? Pochybuji asi tak, že nadále tento limit zvyšovat, při čemž max je 10000 zdá se mi to jako blbost. Jak to můžu ošetřit ? Je to tím, že se připojení neukončují a pořád tak hodnota narůstá ?

Díky za rady
Camo
Profil
BitaSk:
Zaujímavý problém. Dočítal som sa že to môže spôsobovať perzistentné pripojenie(mysql_pconnect), alebo preplnený disk. Trochu by si to mohol upresniť.
BitaSk
Profil
Camo:
Přidám například novou funkci, ktrerá potřebuje připojení do DB ... a pracuje s nějakýma balíkama třeba mám 80 balíků, uživatel spočítá dopravu jednoho z těch balíků a vše je ok...pokud má uživatel 180 balíků a udělá to sáme...znefunkční se mnoho funkcí a když uživatel uloží například zvolenou přepravu, tak tím že se některé funkce nenačetly po chybě max_connections , tak mi to totálně nadělá paseku ve funkcionalitě, tak i v DB... připojení do db je přes Nette s parametrem lazy, zatím je to vyřešené s max connections na 1500 ale to vystačí jen na chvíli :/
tiso
Profil
To vyzerá na zle navrhnutú aplikáciu, bez konkrétnych kódov ťažko radiť čo je zle.
BitaSk
Profil
tiso:
jak zle navrhnutů ? V každé třídě je připojení jako konstruktor a ten využívám ... například
$database = $db->connect();
$database->saveNewUser();
unset($database);

kde je chyba ?
tiso
Profil
BitaSk: chyba je v tom, že vytváraš v tých triedach stále nové spojenia.
Keeehi
Profil
BitaSk:
Ano, spojení vytvoříš jen jednou (resp. ho za tebe vytvoří Nette) a do konstruktoru si ho pak už jen předáváš.
BitaSk
Profil
takže problém je v tom že pokaždé vytvářím nové spojení ? Pokud ho třeba vytvořím 20x a pak už ne tak to nemůže přece narůst na 500 ne ?
Keeehi
Profil
Pokud jich vytvoříš 20, tak ti stačí 25 návštěvníků kteří jsou zároveň na tvé stránce aby jsi byl hned na 500.

Ale i kdyby jsi vytvářel jen 2 tak je to v 99.9% případů zbytečné.
Camo
Profil
BitaSk:
Takto sa v Nette spojenie nevytvára. To sa vytvorí automaticky len raz a do tried sa predáva len objekt $database ktorý to spojenie má vytvorené. Akú používaš knižnicu pre databázu?
BitaSk
Profil
jojo, používám mysql. Ale pak, jak si to spojení mám předat ve všech třídách ? Jak to spojení vytvořím globálně, anichž bych to ukládal do globální proměnné ? Při vytvoření konstruktoru nějaké třídy nemůžu vždy přiřadit například takto ?

class Prispevky{

private $db;

public _construct(){
$this->db = new Db();
}
}

Kdy v new Db() se vytvoří připojení ? Takto by to nešlo ?


a nebo konstruktor třídy database mám takhle

class Database {

 public $connect;

public function __construct() {
  $connection = new Connection("údaje pro připojení do DB", array(
                'lazy' => TRUE
            ));
}
$this->connect = $connection;
}

a použití (předání) v jiné třídě

class Delivery {

    private $db;

    public function __construct() {
        $this->db = new a_Database();
}

// příklad nějaké funkce 
$this->db->getCarriers($user);

Všechny třídy jsem teď tak předělal a v případech kdy by vyskočil error max_connections a skript se ukončil, tak teď žádná chyba a vše je OK. Snad to tak zůstane....
Keeehi
Profil
Ty se vůbec nemáš k databázi připojovat. Ty vlastně řekneš "Nette, chci pracovat s databází, tak mi tady do konstruktoru vlož něco, pomocí čehož se k databázi dostanu" a Nette to udělá. A jak si o to říct?
public function __construct(Nette\Database\Context $db) {
    $this->db = db;
}

public function someMethod() {
    $this->db->query('SELECT ...');
}
BitaSk
Profil
Keeehi:
Ano však v předešlém příkladě už to tak mám... a error již nevyskakuje. Mám vytvořené připojení jen jednou a to předávám v konstruktoru v ostatních třídách... nebo předešlý kód, který jsem publikoval je zase špatný ?
tiso
Profil
BitaSk: „a to předávám v konstruktoru v ostatních třídách
To práve nerobíš. Je rozdiel medzi:
class  A {
    public function __construct($db) {
        $this->db = $db;
    }
}
class  B {
    public function __construct($db) {
        $this->db = $db;
    }
}
a:
class  A {
    public function __construct() {
        $this->db = new Db();//prve spojenie
    }
}
class  B {
    public function __construct() {
        $this->db = new Db();//druhe spojenie
    }
}
BitaSk
Profil
tiso:
Jojo, ted je to naprosto jasné, vytvářel sem i tak pořád nové spojení. A kde prosím tě vezmu $db co je parametrem toho konstruktoru ? To mám uložit jako do globální proměnné ? Nebo vlastně, můžu proměnnou $db vytvořit na začátku dokumentu a pak by měla existovat všude, když se vše includuje do indexu že ?


Vlastně to by tak nešlo.... co když třídy všechny budou dědit DB a tam jenom předám proměnnou $connect ?


Takto je to ten samý problém ? Nebo by to takhle mohlo být ?
class Delivery extends Database {
 
     function getCarriers() {
        return $this->getCarriers(); 
}
}
tiso
Profil
BitaSk: pokiaľ robíš s frameworkom Nette, tak by si mal veci riešiť tak, ako sa riešia v Nette. Keeehi ti naznačil ako, preštuduj si tutoriály na Nette.
BitaSk
Profil
využívám jen DB Nette
Keeehi
Profil
BitaSk:
využívám jen DB Nette
Aha, tak to bylo potřeba říci. Protože kdyby jsi využíval celé Nette, tak právě tu proměnnou $db co je v konstruktoru tam Nette dodá samo.

Takže v nějaké hlavní třídě (controleru nebo něčem co je volá) bych si vytvořil
$database = new Nette\Database\Context(new Nette\Database\Connection($dsn, $user, $password));
A pak už bych jen $database skrz konstruktory posílal níž, na místa, kde se s databází pracuje.

Když tak tady je dokumentace k Nette database.
BitaSk
Profil
Keeehi:
To se omluvám, to byla určitě velká hrubka, že jsem se o tom nezmínil :/ jojo, takže by to mohlo být v příkladu co jsem zvolil výše ? Že mi všechny třídy dědí od třídy database ?
Keeehi
Profil
BitaSk:
Dědění to nevyřeší. Jeden z přístupů je Dependency injection.
class main {
    public function run() {
        $database = new Nette\Database\Context(new Nette\Database\Connection($dsn, $user, $password));
        
        $delivery = new Delivery($database);
        $carriers = $delivery->getCarriers();
        ...
    }
}


class Delivery {
    private $db;

    public function __construct(Nette\Database\Context $db) {
        $this->db = db;
    }
 
     public function getCarriers() {
         $result = $this->db->query('SELECT carriers FROM ...');
         ...
         return $carriers; 
    }
}

Celé to spočívá v tom, že třída Delivery má nějakou závislost, aby mohla pracovat tak ten kdo ji psal se rozhodl, že potřebuje využívat Nette\Database\Context, takže celému světu pomocí konstruktoru řekne "Já sice nevím, kdo mě vytvoří, ale ten kdo to bude mi musí předat instanci třídy (objekt) Nette\Database\Context jinak odmítám pracovat." tudíž tam kde se vytváří instance třídy Delivery se zároveň musí předat i ten Context.
No jo, ale kde se ten Context vezme? No buď je to třída, která ještě není zodpovědná za vytváření spojení do databáze a tak si o to zase konstruktérem požádá ("Hele, já tu pracuji s třídou, která po mě chce Context ale to já nemám na starosti, tak mi to při vytváření předej, jinak nebudu pracovat."), nebo je to už třída, která je za vytváření připojení zodpovědná a tak ho vytvoří a při vytváření nového objektu ho předá.
BitaSk
Profil
Keeehi:
Rozumím, děkuju moc. Pokusím se to předělat, tak aby mi třída DB, jak jsi tu zmínil vytvořila připojení a to jen pak budu posílat dál. Moc jste mi pomohli, díky moc !

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0