0

我的 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?

4

1 回答 1

0

恕我直言,您的方法已经足够好了。尽管我建议对您当前的触发器实现进行 2 处更改(第一个很重要,第二个可以忽略):

  1. 您可能想要一个AFTER而不是BEFORE触发器。这意味着您要确保成功完成UPDATE转入资金。触发器通常用于更改正在插入或更改的行的值或阻止对该行的操作(例如违反约束或发出)。accountsINSERTBEFORESIGNAL

  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触发器以正确维持帐户余额。


现在,如果您不希望有大量数据,您也可以考虑创建一个视图或通过其他方式(单独的方法)通过简单的查询即时计算帐户余额。这样您就不需要维护账户价值、处理可能发生的差异,而且它总是准确的。

于 2013-07-28T03:20:09.017 回答