【发布时间】:2018-04-13 13:48:58
【问题描述】:
我使用 laravel5.5 的数据库事务进行在线支付应用。我有一个 company_account 表来记录每次付款(type、amount、create_at、gross_income)。创建新记录时,我需要访问最后一条记录的gross_income。所以我需要在事务的时候用读写表锁来锁表,以避免同时进行多次支付。
我参考了 laravel 的文档,但我不确定事务是否会锁定表。如果事务会锁表,锁的类型是什么(读锁、写锁或两者兼有)?
DB::transaction(function () {
// create company_account record
// create use_account record
}, 5);
代码:
DB::transaction(function ($model) use($model) {
$model = Model::find($order->product_id);
$user = $model->user;
// **update** use_account record
try {
$user_account = User_account::find($user->id);
} catch (Exception $e){
$user_account = new User_account;
$user_account->user_id = $user->id;
$user_account->earnings = 0;
$user_account->balance = 0;
}
$user_account->earnings += $order->fee * self::USER_COMMISION_RATIO;
$user_account->balance += $order->fee * self::USER_COMMISION_RATIO;
$user_account->save();
// **create** company_account record
$old_tiger_account = Tiger_account::latest('id')->first();
$tiger_account = new Tiger_account;
$tiger_account->type = 'model';
$tiger_account->order_id = $order->id;
$tiger_account->user_id = $user->id;
$tiger_account->profit = $order->fee;
$tiger_account->payment = 0;
$tiger_account->gross_income = $old_tiger_account-> gross_income + $order->fee;
$tiger_account->save();
}, 5);
【问题讨论】:
-
事务和锁是为不同目的而构建的两种不同的东西。您不需要锁定,也不需要限制一次付款。请阅读stackoverflow.com/questions/4226766/… 和其他类似内容,了解事务和回滚如何工作的示例。
-
@AlexBlex 您的链接很有帮助。但我认为我需要同时使用锁定(读取和写入)和事务,因为在事务中我将访问最后一条记录的总收入,然后计算新记录的当前总收入。我是不是走错路了。
-
我找到了一个值得讨论的答案,stackoverflow.com/questions/3106737/…。说明我们在交易过程中保证没有其他用户更改。
-
如果它在同一个表中,很可能你既不需要锁也不需要事务。单个原子更新就足够了。如果您使用表架构和您尝试在事务中执行的查询更新问题,很高兴通过示例给出完整的答案。
-
@AlexBlex 我已经用代码示例更新了我的问题。
标签: php database laravel transactions table-locking