2015-10-09 4 views
2

У меня есть простой код, который использует транзакцию db в Yii2, это обновляет баланс пользователя и добавляет новую запись в историю баланса пользователя.Db Транзакции в Yii2 с обратными вызовами

//User model 
public function changeBalance(UserBalanceHistory $balance) 
{ 
    $balance->balance = $this->balance; 
    $balance->user_id = $this->id; 
    $this->balance = $this->getBalance() + $balance->getDelta(); 

    $transaction = Yii::$app->db->beginTransaction(); 
    try { 
     if ($balance->save() && $this->save()) { 
      $transaction->commit(); 
      return true; 
     } 
    } catch (Exception $e) { 
     Yii::error($e->getMessage()); 
    } 

    $transaction->rollBack(); 
} 

Для сохранения целостности данных я должен использовать транзакции db. Но обработка БД сделок, как выше, требует много строк кода, так что я создал такую ​​функцию, которая мобилизует свои коды:

function dbTransaction(callable $callback) 
{ 
    $transaction = Yii::$app->db->beginTransaction(); 

    try { 
     //if callback returns true than commit transaction 
     if (call_user_func($callback)) { 
      $transaction->commit(); 
      Yii::trace('Transaction wrapper success'); 
     } 
    } catch (\Exception $e) { 
     $transaction->rollBack(); 
     throw $e; 
    } 
    $transaction->rollBack(); 
} 

С помощью этой функции можно обрабатывать транзакции, как это:

//User model 
public function changeBalance(UserBalanceHistory $balance) 
{ 
    dbTransaction(
     function() use ($balance) { 
      $balance->balance = $this->balance; 
      $balance->user_id = $this->id; 
      $this->balance = $this->getBalance() + $balance->getDelta(); 

      return $balance->save() && $this->save(); 
     } 
    ); 
} 

Как вы видите, второй способ очень удобно, используя транзакции. Но по этому вопросу я не уверен, что функция dbTransaction работает правильно или нет? Обзор кода и примечания, которые указывают на потенциальные проблемы, приветствуются. Благодаря

+0

должен быть перемещен в http://codereview.stackexchange.com/ – robsch

ответ

0

удалить код $transaction->rollBack(); Перед последней строкой, потому что этот код всегда откатить и отмену транзакции

function dbTransaction(callable $callback) 
{ 
    $transaction = Yii::$app->db->beginTransaction(); 

    try { 
     //if callback returns true than commit transaction 
     if (call_user_func($callback)) { 
      $transaction->commit(); 
      Yii::trace('Transaction wrapper success'); 
     } 
    } catch (\Exception $e) { 
     $transaction->rollBack(); 
     throw $e; 
    } 
    //$transaction->rollBack(); 
} 
Смежные вопросы