2016-06-01 35 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方法可以防止任何并发控制,除非在检索数据之前启动事务,这不仅效率低下,而且对代码也很烦(难以维护)。 –