Podivnosti s referencemi do jedné tabulky (postgresql)

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
jik
Člen | 146
+
0
-

Zdravím,
na systému opensuse 13.1, apache 2.4.6, php 5.4.20, postgresql 9.2.4, nette 2.0.14. Podobně i opensuse 12.3 s příslušnými verzemi. Mám tabulku, do které se odkazuji z několika jiných tabulek (v současné době aplikace má celkem >20 tabulek s řadou relací mezi nimi, ale problém mám s relacemi do této jediné tabulky):

CREATE TABLE process (
id SMALLINT PRIMARY KEY,
role_acc SMALLINT,
role_fin SMALLINT,
icon VARCHAR(10), -- toto je nazev ikony k zobrazeni
nazev VARCHAR(40)
);

Tabulku používám v šablonách k zobrazování položky nazev, nebo ikony, typicky:

<span class=\"icon {$pozemek->process->icon}\"></span>
{$lv->process->nazev}

Problém mám s tím, že v případě této tabulky se mi čas od času (ne vždy, ale občas to jakoby zjankovatí a pak nepomáhá ani smazat cache) stane, že to na těchto polích hlásí „Trying to get property of non-object“, ačkoliv, jak jsem mnohokrát prověřoval, příslušné hodnoty process_id zcela určitě nejsou mimo tabulku process. Jindy se to zase zklidní a jede bez problémů, jak má. Pokud namísto ikon,nebo názvů zobrazím jen process_id, jsou všude regulérní hodnoty.
Dnes jsem si všiml, že v apačím logu jsou zprávy typu:
AH00052: child pid 3385 exit signal Segmentation fault (11)
Není to nějká kolize jmen? Podobné chyby se mi dříve objevovaly častěji a vesměs jsem je řešil mazáním cache, ale s nějakou letní verzí Nette (~2.0.10 nebo 12) se to ‚zklidnilo‘ – s touto jedinou výjimkou. Dnes po opětných problémech jsem nasadil 2.0.14 a nic se nezměnilo.

hrach
Člen | 1834
+
0
-

Pises, ze smazani chache nepomuze. Co tedy pomuze?

jik
Člen | 146
+
0
-

hrach napsal(a):

Pises, ze smazani chache nepomuze. Co tedy pomuze?

To kdybych věděl. Prostě po nějaké době se to umoudří. Dnes večer to zase začalo blbnout, uvidíme … (dnes jsem již rezignoval a zítra zkusím na druhé mašině s opensuse 12.3).

Jo, jednu věc jsem si uvědomil: stává se mi to (naštěstí) pouze na počítačích, na kterých aplikaci vyvíjím. Když už to začne chodit a přenesu to na server, tak to nezlobí. Alespoň na to nepatuji. Ale při vývoji se mi to stalo již povícekrát, jednu dobu jsem to „řešil“ nahrazením kontrukce

$lv->process->icon

za konstrukci

$lv->ref('process','process_id')->icon

ale dnes to tímto způsobem nešlo.

Editoval jik (4. 1. 2014 23:29)

jik
Člen | 146
+
0
-

Tak dneska vše běželo zcela bez problémů. Ráno na notebooku bez chyby a teď jsem se vrátil na stolní počítač – ale napřed jsem provedl vacuum databáze … tak mě napadá, jestli by se nemohlo jednat o nějaký problém s časovou sousledností – že nějaká operace nad db se provede opožděně a php již pokračuje s tím, že data prostě nejsou? Databáze má celkem okolo 150 tisíc záznamů, postupně se vyvíjí a doplňuje – a jedno z posledních doplnění bylo právě to, že jsem vytvořil tabulku process a v několika tabulkách původně obsahujících položku

process smallint

nejprve doplnil položku

alter table ... add column process_id smallint referencess process

Nakonec jsem odstranil položku process

alter table ... drop column process

A od té doby čas od času s tím mám potíže. Jediné, co mě napadá, že databáze během vývoje není zcela konsolidovaná a některé operace zvládne poněkud opožděně, na což php nečeká. Jeví se mi to jako blbost, ale nic jiného mě nenapadá.

jik
Člen | 146
+
0
-

Tak se chybička vrátila. Mám situaci, která je zatím zcela opakovatelná. Je to na Nette 2.1.2 a mám „kolečko“ mezi 2 presentery:

  1. NemovityPresenter a v něm Default – zobrazuje sestavu záznamů z tabulek pozemek a stavba (zjednodušeně):
	protected function startup() { //pouze nastaveni promennych
	}

	public function actionDefault($id) {
		...
		$this->a_pozemky  = $this->s_pozemek->getPozemkyLv($id)->where("process_id < {$konstanta}");
	}

	public function renderDefault($id) {
		foreach ($this->a_pozemky as $o_pozemek) {
			$pozemek = new StdClass;
			$pozemek->id        = $o_pozemek->id;
			... - data potrebna do sestavy
			$pozemek->icon      = $o_pozemek->process->icon; // zde se zjevuje chyba "Trying to get property of non-object"
			$pozemky[] = $pozemek;
			unset($pozemek);
		}
		$this->setView('defaultrep');
		$this->template->form     = $this['defaultrepForm'];
	}
  1. PozemkovyPresenter a v něm Edit – zobrazuje 1 záznam z tabulky pozemků (zjednodušeně):
	public function actionEdit($id) {
		$o_pozemek = $this->s_pozemek->getPozemek($id);
		... data potrebna do sestavy
		$this["editpozForm"]->setDefaults($this->o_pozemek); // nastavení výchozích hodnot
	}

	public function renderEdit($id) {
		...
		$this->template->form     = $this['editpozForm'];
		$this->setView('edit');}
	}

	public function editpozFormSubmitted(Form $form) {
		//uprava a kontrola dat
		//ukladani
		//aktualizace souvisejicich dat
		$this->redirect('Nemovity:', $lv_id);
	}

Tabulky:

CREATE TABLE process (
	id 				SMALLINT PRIMARY KEY,
	icon 			VARCHAR(10),
	...
);
CREATE TABLE pozemek (
	id 				SERIAL PRIMARY KEY,
	lv_id 			INTEGER NOT NULL REFERENCES lv,
	cislo 			INTEGER,
	podlomeni  		INTEGER,
	rada 			SMALLINT,
	...
	process_id 		SMALLINT REFERENCES process DEFAULT 0,
	...
);

Problém je v tom, že po návratu z PozemkovyPresenter pravidelně zhavaruje v NemovityPresenter, když má přečíst jméno ikony. Pokud však před uložení smažu cache, vše projde, jak má. Stejně tak vše je v pořádku, pokud do této sestavy vstupuji odjinud. Kromě uvedeného PozemkovyPresenter je zde i analogický StavebniPresenter s úplně stejnou chybou: otevřu stavbu, uložím a zhavaruje na analogickém místě, kde se načítá ikona stavby.