2016-06-20 120 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);