2016-06-01 6 views
3

Я здесь сегодня, потому что не могу понять, в чем проблема с моими транзакциями, используя RedbeanPHP. Я предполагаю, что проблема связана с значением «autocommit» MySQL, поскольку он всегда включен.Операция Redbean не работает

Короче говоря:
1) R::freeze(true); был выдан,
2) пытался как R::begin() .. R::commit() и R::transaction($callback) синтаксис

Вот простой класс с тестируемым кодом:

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

    } 
} 

Выполнение функции test() с большим количеством скриптов PHP одновременно (я пробовал с 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. Часть кода, которая имеет дело с синхронным доступом (как мьютексом), является обязательной.

Оставив здесь вопрос, так как я думаю, что он может быть полезен другим программистам.

Cheers

+0

Эта ссылка фактически не имеет отношения к проблеме, с которой вы столкнулись. Проблема с beans заключается в том, что данные извлекаются из базы данных, затем вы обновляете значение и, наконец, возвращаете новое значение в базу данных. В более классических операциях РСУБД вы просто делаете «UPDATE test SET alivesince = alivesince + 1 WHERE ...». Подход RedBeans предотвращает любой контроль параллелизма, за исключением случаев, когда вы начинаете транзакцию перед извлечением данных, что не только неэффективно, но и раздражает код (и трудно поддерживать). –