Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ArielMejiaDev/36a20e715c79955d8932208747fe5c2e to your computer and use it in GitHub Desktop.
Save ArielMejiaDev/36a20e715c79955d8932208747fe5c2e to your computer and use it in GitHub Desktop.
Optimistic Locking for Transaction
<?php
function transfer($fromAccountId, $toAccountId, $balance)
{
$fromQuery = Account::whereId($fromAccountId);
if (! $fromQuery->exists()) {
throw new InvalidAccountException();
}
$toQuery = Account::whereId($toAccountId);
if (! $toQuery->exists()) {
throw new InvalidAccountException();
}
do {
$fromAccount = $fromQuery->first();
if ($fromAccount->balance < $amount) {
throw new InsufficientBalanceException();
}
$updated = Account::whereId($fromAccountId)
->where('updated_at', '=', $fromAccount->updated_at)
->update(['balance' => $fromAccount->balance - $amount]);
} while (! $updated);
do {
$toAccount = $toQuery->first();
$updated = Account::whereId($toAccountId)
->where('updated_at', '=', $toAccount->updated_at)
->update(['balance' => $toAccount->balance + $amount]);
} while (! $updated);
$transaction = new Transaction();
$transaction->from_account_id = $fromAccountId;
$transaction->to_account_id = $toAccountId;
$transaction->amount = $amount;
$transaction->save();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment