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