Skip to content

Instantly share code, notes, and snippets.

@aslrousta
Last active June 1, 2024 03:50
Show Gist options
  • Save aslrousta/70e9d58f9027c3bfe1f38b50d11eef2c to your computer and use it in GitHub Desktop.
Save aslrousta/70e9d58f9027c3bfe1f38b50d11eef2c to your computer and use it in GitHub Desktop.
Pessimistic Locking for Transaction
<?php
function transfer($fromAccountId, $toAccountId, $amount)
{
DB::beginTransaction();
try {
$fromQuery = Account::whereId($fromAccountId);
if (! $fromQuery->exists()) {
throw new InvalidAccountException();
}
$toQuery = Account::whereId($toAccountId);
if (! $toQuery->exists()) {
throw new InvalidAccountException();
}
$fromAccount = $fromQuery->lockForUpdate()->first();
if ($amount > $fromAccount->balance) {
throw new InsufficientBalanceException();
}
$toAccount = $toQuery->lockForUpdate()->first();
$toAccount->balance += $amount;
$toAccount->save();
$fromAccount->balance -= $amount;
$fromAccount->save();
$transaction = new Transaction();
$transaction->from_account_id = $fromAccountId;
$transaction->to_account_id = $toAccountId;
$transaction->amount = $amount;
$transaction->save();
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
}
@Mane-Olawale
Copy link

Thanks for this, this is a very useful gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment