2016-06-20 93 views
0

几乎花了我整整一天的时间来解决有关交易的问题,但我失败了。 我的要求是在一个事务中在表主题和表topic_data中插入新记录。 我有这样的代码:Phalcon PDO交易不正常

// database connection 
$di->set('db', function() use($conf) { 
    return new \Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter([ 
     'host' => $conf->db->host, 
     'username' => $conf->db->username, 
     'password' => $conf->db->password, 
     'dbname' => $conf->db->dbname, 
     'options' => [ 
      \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, 
      \PDO::ATTR_PERSISTENT => true, 
      \PDO::ATTR_AUTOCOMMIT => false 
     ] 
    ]); 
}); 

// transaction code 
public function create($params) { 
    $this->db->begin(); 

    $id = \Idalloc::next(); 
    $topic = new Topic(); 
    $topic->id = $id; 
    $topic->ctime = $_SERVER[ 'REQUEST_TIME' ]; 

    $tags = $params[ 'tags' ]; 

    $params[ 'tags' ] = implode(',', $tags); 
    $topic->assign($params); 

    if($topic->save() === false) { 
     $this->db->rollback(); 
     return false; 
    } 

    for($i = 0, $l = count($tags); $i < $l; ++$i) { 
     $topicTag = new TopicTag(); 
     $topicTag->tag_id = $tags[ $i ]; 
     $topicTag->topic_id = $id; 
     $topicTag->type = $params[ 'type' ]; 
     if($topicTag->save() === false) { 
      $this->db->rollback(); 
      return false; 
     } 
    } 

    var_dump($this->db->isUnderTransaction()); 

    $this->db->commit(); 
    return $id; 
} 

的失败:

  • 如果我不设置\PDO::ATTR_PERSISTENT => true,方法“创造”,返回的$ id和var_dump($this->db->isUnderTransaction())是真实的,但没有数据被插入到两个表主题,并表topic_tag

  • 如果我设置\PDO::ATTR_PERSISTENT => true,我会用异常: [Tue, 21 Jun 16 02:16:21 +0800][ERROR] PDOException: There is no active transaction 和S直到未能将数据插入到表格主题中,但新的记录出现在表格topic_tag中。

  • 如果我只保留两个部分中的一个,它将会很好地工作。

我该如何解决这个问题,是否有一种简单的方法来创建手动事务?

+0

'\ PDO :: ATTR_AUTOCOMMIT => FALSE'(假设驱动程序支持)基本意思是 “总是自动启动一个事务”。我想你应该打开如果你想手动开始交易。 –

+0

@ÁlvaroGonzález打开后,我会得到'没有活动事务'。 – LCB

回答

1

我发现了这个问题的解决方案。 DI中设置的'db'必须共享。因此,有需要另一个参数 “TRUE”:

// database connection 
$di->set('db', function() use($conf) { 
    return new \Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter([ 
     'host' => $conf->db->host, 
     'username' => $conf->db->username, 
     'password' => $conf->db->password, 
     'dbname' => $conf->db->dbname, 
     'options' => [ 
      \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, 
      \PDO::ATTR_PERSISTENT => true, 
      \PDO::ATTR_AUTOCOMMIT => false 
     ] 
    ]); 
}, true);