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