MySQL a transakce v Nette 2.0.3

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

Dobrý den,

chtěl bych se zeptat – mám problémy s transakcemi, chtěl bych, aby se tento kód vykonal v jedné transakci.

Už nevím, jak dál, můžete někdo prosím poradit?

Děkuji

$x = $this->context->params['database'];

$this->db = new Connection($x['dsn'], $x['user'],$x['password']);

foreach($result as $row){

	try{
		$this->db->beginTransaction();

		$this->db->table('table')->insert(array( ... ));  //toto se vykoná, i když
		$this->db->table('client')->insert(array(...)); //tady to spadne
		$this->db->table('table2Archive')->insert($row);
		$this->db->table('table2')->where(array('id' => $row->id))->delete();

		$this->db->commit();
	} catch (Exception $e) {
		$this->db->rollback();

		Debugger::log($e);
		$this->flashMessage('problem...', 'error');
		$this->redirect('Error:');
	}
}
Jan Pacák
jtousek
Člen | 951
+
0
-

Pomůže tohle?

$this->db->exec('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
$this->db->beginTransaction();

EDIT: Jo a doufám že tabulky máš uložené v enginu InnoDB.

Editoval jtousek (16. 6. 2012 14:27)

pacaj2am
Člen | 3
+
0
-

:-(

MyISAM

jtousek
Člen | 951
+
0
-

Tim se to vysvětluje, MyISAM neumí transakce, přepni na InnoDB a mělo by to fungovat i bez toho mého kódu.

pacaj2am
Člen | 3
+
0
-

Ok, děkuji moc… :-)

JPA

Už to jede… :-)

miler
Člen | 75
+
0
-

V prvním postu je try/catch sekce v presenteru (beru podle redirectu). Když by ale práce s databází měla být v modelu, jak byste pak pracovali s výjimkami? Měl bych vracet hodnotu po úspěšném commitu, resp. FALSE pokud jsem v catch větvi, nebo to nezachytávat a nechat to až do presenteru? Díky.

duke
Člen | 650
+
0
-

Z hlediska čistoty kódu je lepší používat výjimky než při chybě vracet FALSE. Hlavní výhodou je to, že výjimku si můžeš zachytit až tam, kde to potřebuješ a ne nutně řešit vrácené FALSE na všech úrovních.
Pokud by to ale znamenalo příliš časté vyhazování výjimek, může to být na úkor efektivity kódu (tj. může to zvýšit zátěž serveru). Takže je třeba zvážit i tento pohled na věc.

miler
Člen | 75
+
0
-

Díky, takže bych měl udělat v modelu standardně try/catch, přičemž v try větvi provést transakci a v catch větvi případně volat

$this->connection->rollback();

a pak vyhodit ještě jednu vlastní výjimku?

duke
Člen | 650
+
0
-

Ano, toto je IMHO čistý způsob.

Pokud by to příliš zatěžovalo server, můžeš to vždy nějak zoptimalizovat (a pak třeba trochu toho luxusu jež poskytují výjimky obětovat).

miler
Člen | 75
+
0
-

Fajn, díky.