2016-06-01 5 views
3

Ich bin heute hier, weil ich nicht herausfinden kann, was das Problem mit meinen Transaktionen mit RedbeanPHP ist. Ich vermute, dass das Problem mit dem "Autocommit" -Wert von MySQL lag, da dieser immer eingeschaltet ist.Redbeans Transaktion funktioniert nicht

Lange Rede kurzer Sinn:
1) R::freeze(true); erteilt wurde,
2) versucht, beide R::begin() .. R::commit() und R::transaction($callback) Syntax

Hier ist eine einfache Klasse mit einem Testcode:

class TestTransactions{ 
    public function testme($args){ 
    $tstname = $args; 
    $src = R::findOne('batchscripts', 'batchclass = :tstname', 
     array(':tstname' => $tstname)); 

    sleep(2); 

    if($src){ 
     $src->alivesince = intval($src->alivesince) + 1; 
     R::store($src); 
    } else { 
     $bean = R::dispense('batchscripts'); 
     $bean->batchclass = $tstname; 
     $bean->alivesince = 0; 
     $bean->start = R::$f->now(); 
     R::store($bean); 
    } 
    } 

    public function testCallback(){ 
    $that = &$this; 
    R::freeze(true); 
    try{ 
     $ret2 = R::transaction(function() use ($that){ 
     //uncomment me to see autocommit value 
     //$g = R::getAll("show global variables like 'autocommit'"); 
     //$g = array_pop($g); 
     //var_dump($g); 
     $that->testme('instance'); 
     }); 
    } catch (Exception $e){ 
     throw $e; 
    } 

    } 

    public function testProcedural(){ 
    R::freeze(true); 
    try{ 
     R::begin(); 
     $this->testme('instance2'); 
     R::commit(); 
    } catch (Exception $e) { 
     R::rollback(); 
     throw $e; 
    } 

    } 

    public function test(){ 

    $this->testCallback(); 
    $this->testProcedural(); 

    } 
} 

Ausführung der test() - Funktion mit mehreren PHP-Skripten gleichzeitig (ich habe mit 12 versucht), Datenbankeinträge sind nicht korrekt:

Ich erwarte, dass ich

bekam ich

batchclass: 'instance', alivesince: 11 
batchclass: 'instance2', alivesince: 11 

statt haben

batchclass: 'instance', alivesince: 7 
batchclass: 'instance2', alivesince: 7 

Oder sogar

batchclass: 'instance', alivesince: 5 
batchclass: 'instance2', alivesince: 5 

abhängig von dem Moment die Skripte ausgeführt werden.

Was fehlt mir hier?

Danke

Antwort

0

das Problem aus einer anderen Perspektive sehen, habe ich gefunden, was ich fehlte.

Wie in einem anderen Beitrag a multithread transaction erwähnt, ist nicht mit MySQL anwendbar. Ein Teil des Codes, der den synchronisierten Zugriff (als Mutex) behandelt, ist ein Muss.

Hier die Frage zu verlassen, da ich denke, dass es für andere Programmierer nützlich sein kann.

Cheers

+0

Dieser Link ist eigentlich irrelevant für das Problem, das Sie aufgetreten sind. Das Problem mit Beans besteht darin, dass die Daten aus der Datenbank extrahiert werden. Anschließend aktualisieren Sie den Wert, und Sie fügen den neuen Wert schließlich wieder in die Datenbank ein. In klassischeren RDBMS-Operationen würden Sie einfach "UPDATE test SET alivesince = alivesin + 1 WHERE ..." ausführen. Der RedBeans-Ansatz verhindert die Steuerung des gemeinsamen Zugriffs, außer wenn Sie vor dem Abrufen der Daten eine Transaktion starten, die nicht nur ineffizient, sondern auch lästig ist (und schwer zu warten ist). –

Verwandte Themen