在Yii中使用触发器时如何使用事务

时间:2013-07-26 12:30:05

标签: mysql yii triggers transactions

我的MySQL数据库中有accountsmoney个表,所以如果任何行添加到钱,accounts.balance应该更新,首先我通过Active Record和Transaction

$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;

触发器足以确保更新帐户表而不使用事务?如果您的答案为否,我如何组合触发器,事务和ActiveRecord?

1 个答案:

答案 0 :(得分:0)

恕我直言,你的方法已经足够好了。虽然我建议对当前的触发器实现进行2次更改(首先是重要的第二次,你可以忽略):

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

  2. 由于你的触发器是一个语句触发器,你可以放弃BEGIN ... END阻止。这样您就不需要更改DELIMITER

  3. 据说你的触发器可能看起来像

    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方法)通过简单查询即时计算帐户余额。这样你就不需要维护账户价值,处理可能发生的差异,而且总是很精确。