我有在 Yii2 中使用 DB 事务的简单代码,这会更新用户余额并向用户余额历史记录添加新记录。
//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();
}
我应该经常使用数据库事务来保存数据完整性。但是像上面那样处理数据库事务需要很多代码行,所以我创建了以下函数来调动我的代码:
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
功能是否正常工作?代码审查和注释哪些点潜在问题值得赞赏。谢谢
请您参考如下方法:
删除您的代码 $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();
}