【问题标题】:Redbean's transaction not workingRedbean 的事务不工作
【发布时间】:2016-09-30 17:03:06
【问题描述】:

我今天来到这里是因为我无法弄清楚我使用 RedbeanPHP 进行的交易有什么问题。我猜问题出在 MySQL 的“自动提交”值上,因为它始终处于开启状态。

长话短说:
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();

  }
}

同时使用多个 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

取决于我运行脚本的时间。

我在这里错过了什么?

谢谢

【问题讨论】:

    标签: php mysql transactions redbean


    【解决方案1】:

    从不同的角度看待问题,我找到了我所缺少的。

    正如另一篇文章中所述,a multithread transaction 不适用于 MySQL。处理同步访问(作为互斥体)的部分代码是必须的。

    把这个问题留在这里,因为我认为它对其他程序员有用。

    干杯

    【讨论】:

    • 该链接实际上与您遇到的问题无关。 bean 的问题是从数据库中提取数据,然后更新值,最后将新值放回数据库中。在更经典的 RDBMS 操作中,您只需执行“UPDATE test SET alivesince = alivesince + 1 WHERE ...”。 RedBeans 方法阻止了任何并发控制,除非您在检索数据之前启动事务,这不仅效率低下而且对代码来说很烦人(并且难以维护)。
    猜你喜欢
    • 2014-11-25
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    相关资源
    最近更新 更多