2013-07-26 37 views
0

我在MySQL数据库accountsmoney表,因此,如果添加任何行到钱,accounts.balance应该更新,首先我做到了通过活动记录和交易如何在Yii中使用触发器时使用交易

$transaction = $connection->beginTransaction(); 
try { 
    if ($createModel->save()) { 
       $account = $createModel->accounts; 
       $account->balance += $createModel->amount; 
       if ($account->save()) 
        $transaction->commit(); 

    } 
} catch(Exception $e){ 
     $transaction->rollBack(); 
} 

现在我把它改成$createModel->save(),创造触发更新accounts表,

CREATE TRIGGER before_insert_money BEFORE INSERT ON money 
    FOR EACH ROW 
     BEGIN 
       UPDATE accounts SET balance=balance+NEW.amount WHERE id=NEW.accounts_id; 
     END; 

是引发足够,以确保有关使用事务更新帐户的表呢?如果你的answe r是否,我怎样才能结合触发器,事务和ActiveRecord?

+0

你为什么要通过触发器*交易有什么问题? – DCoder

+0

我认为它速度更快,它可以帮助我拥有更薄的控制器。 –

+2

*思考*某事更快与*测量*并不相同,实际上速度更快。即使速度稍微快一点,你仍然使用煎饼杀死黄蜂,你的解决方案可能会起作用,但这不是触发器的作用。 – DCoder

回答

0

恕我直言,你的方法是够好的。虽然我建议2名更改当前触发器实现(第一个是你可以忽略重要的第二):

  1. 你可能想要一个AFTER而不是BEFORE触发。这意味着你想让UPDATEaccounts确保INSERT成功完成。 BEFORE触发器通常用于更改要插入或更改的行的值,或者防止该行上的操作(例如,违反约束或发出SIGNAL)。

  2. 由于您的触发器是一个语句触发器,因此您可以消除BEGIN ... END块。这样你就不需要改变DELIMITER

话虽这么说你的触发器可能看起来像

TRIGGER before_insert_money 
BEFORE INSERT ON money 
FOR EACH ROW 
    UPDATE accounts 
    SET balance = balance + NEW.amount 
    WHERE id = NEW.accounts_id; 

剩下的问题你允许更新和删除你的钱记录?如果是,那么您必须执行互补AFTER UPDATEAFTER DELETE触发器才能正确保持帐户余额。


现在如果您不期望获得大量数据,您可能还会考虑创建视图或通过其他方式(separete方法)通过简单查询计算帐户余额。这样你就不需要维护账户价值,处理可能发生的差异,而且总是精确的。

+0

@ Moein7tl它有帮助吗? – peterm