E
E
Evgeny Khripunov2018-08-14 12:21:39
Laravel
Evgeny Khripunov, 2018-08-14 12:21:39

How to properly organize an intra-site currency transfer transaction between users in laravel?

The user sends a request to the server to transfer part of the funds from his account to the account of another user.
At the database level, the balance field for each user is: unsignedInteger
The request is validated:

$this->validate($request, [
   'receiver_id'=>'required',
   'money'=>'required|integer',
]);

The following transaction is executed:
DB::transaction(function () use ($request) {
    //Снимаем деньги со счета пользователя 
    User::where('id', Auth::user()->id)->decrement('balance', $request->money); 
    //Переводим деньги другому пользователю
    User::where('id', $request->receiver_id)->increment('balance', $request->money);
    //Добавляем в бд запись о транзакции
    $transaction = MoneyTransaction::create($request->all() + ['sender_id' => Auth::user()->id, 'type_id' => 2]);
});

1) Is the structure of the transaction organized correctly?
2) Is it necessary to check that the user has enough money in the account (more than $request->money) if the balance field in the database is unsignedInteger ?
3) If so, should this be done in the transaction itself?
4) And do I need to use any sharedLock/lockForUpdate locks ?
Thanks in advance!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
miki131, 2018-08-14
@fannyfan414

DB::transaction(function () use ($request) {
            $user = User::where('id', Auth::user()->id)->lockForUpdate()->first();
            if ($user->balance < $request->money) {
                throw new \Exception('Insufficient funds');
            }
            //Снимаем деньги со счета пользователя 
            $user->decrement('balance', $request->money);
            //Переводим деньги другому пользователю
            User::where('id', $request->receiver_id)->increment('balance', $request->money);
            //Добавляем в бд запись о транзакции
            $transaction = MoneyTransaction::create($request->all() + ['sender_id' => $user->id, 'type_id' => 2]);
        });

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question