Oznámení
Transakce a firebird
před 9 lety
- wotaen
- Člen | 82
Ahoj všichni, mám problém s transakcema ve firebirdu. Používám
firebird driver od Romana Sklenáře firebird.php…problém je
následující
Mám třídu X, privátní property $connection, která se naplní při
vytváření instance
<?php
$this->connection = dibi::getConnection();
?>
Třída X má dvě metody, read a write.
<?php
function write($test)
try {
$this->connection->begin();
$this->connection->update('tests',array(
'taken' => count($test->sentences),
'percentage' => $test->getPercentage()
))
->where('id=%i',$test->id)
->execute();
}
$this->connection->commit();
} catch (Exception $exception) {
$this->connection->rollback();
throw $exception;
}
?>
a metoda read je prosté
<?php
$this->connection->query('nacti posleni aktualizovany test');
?>
Problém je v tom, že když zavolám write a následně read, tak read
nevidí změny provedené writem. Pokud odstraním transakci z write (begin a
commit), tak vše najednou jede jak má.
Je možné že to ani nemá souvislost s dibi či driverem od Romana…ale už
jsem v koncích.
Díky, Michal
Editoval wotaen (11. 2. 2010 11:52)
před 9 lety
- romansklenar
- Člen | 657
Pár věcí mě napadá:
- nepoužíváš tam třeba někde savepointy?
- nemůže se stát, že transakce zůstane otevřená?
- nesouvisí to s problémem souběhu transakcí a jejich izolací?
Protože takový kus kódu, který jsi tu dal nám v projektu funguje (i se savepointy) bez problémů.
před 9 lety
- wotaen
- Člen | 82
romansklenar napsal(a):
Pár věcí mě napadá:
- nepoužíváš tam třeba někde savepointy?
- nemůže se stát, že transakce zůstane otevřená?
- nesouvisí to s problémem souběhu transakcí a jejich izolací?
Protože takový kus kódu, který jsi tu dal nám v projektu funguje (i se savepointy) bez problémů.
V rámci čitelnosti jsem ten vkládaný kód ořezal…možná to bylo na škodu věci. Teď jsem doma a nemám u sebe kód, mrkmu na to v pondělí, ale z hlavy se problém projevuje následovně…
Nejprve zavolám read($test), v test se volá ‚select * from
generate_test(xxx)‘ a procedura generate_test vytvoří nový test (jeden
záznam v tabulce X a 6 záznamů v tabulce Y, navíc je procedure selectable
a po každém insertu do Y je suspend) a vrátí id a nějaké další data
z Y. Pokud dám po vykonání ‚vyber posledne vlozeny test‘ tak se to
vybere. Ale v případě, že je první select obalený transakcí, tak druhý
už nic nevrátí (i přestože na první jsem zavolal commit). Související
problém asi bude, že když první select (generate_test) je v transakci a
druhým query smažu test, tak mi to hodí deadlock, že je otevřená
transakce…ale jak to?! Vždyť jsem ji zavřel.
Myslím, že problém asi opravdu bude v tom, že transakce při prvním
selectu se nezavře (i přestože jí to řeknu), ale proč, nechápu.
Savepointy, asi, nepoužívám, resp. firebird.php je nepoužívá. Při
ibase_trans jsem zkoušel všechny možné typy izolací, ale ani jedno nevedlo
ke kýženému výsledku.
Pokud tě nic nenapadne, nebo to celé zní příliš obecně, tak v pondělí
vložím kus opravdového kódu.
Dík, Michal
před 9 lety
- wotaen
- Člen | 82
Sypu si popel na hlavu, problém byl v tom, že jsem měl ještě někde jinde update, který běžel v defaultní php transakci a tím pádem update z jiné transakce skončil deadlockem :(