2016-06-01 41 views
3

今天我來到這裏,因爲我無法弄清楚使用RedbeanPHP進行交易的問題。我想問題在於MySQL的'autocommit'值,因爲它始終處於ON狀態。Redbean的交易不起作用

長話短說:
1)R::freeze(true);已經發出,都嘗試R::begin() ... R::commit()R::transaction($callback)語法

這裏
2)是一個簡單的類與測試代碼:

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(); 

    } 
} 

用更多的PHP腳本同時運行test()函數(我用12試過),數據庫條目不正確:

我希望有

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

相反,我得到了

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

甚至

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

取決於我運行的腳本的時刻。

我在這裏錯過了什麼?

謝謝

回答

0

從不同的角度看待問題,我發現我錯過了什麼。

正如另一篇文章a multithread transaction所述使用MySQL不適用。處理syncronized訪問(作爲互斥體)的一部分代碼是必須的。

離開這裏的問題,因爲我認爲它可以是有用的其他程序員。

乾杯

+0

該鏈接實際上與您遇到的問題無關。 bean的問題在於數據是從數據庫中提取的,然後更新值並最終將新值重新放入數據庫中。在更經典的RDBMS操作中,您只需執行「更新測試SET alivesince = alivesince + 1 WHERE ...」。 RedBeans方法可以防止任何併發控制,除非在檢索數據之前啓動事務,這不僅效率低下,而且對代碼也很煩(難以維護)。 –