You're not using DB locking, so the second query read the original data and then just overwrote the "$400" with the "$90". This is a very simple race condition.
When doing transactions like this, you should be doing pessimistic locking as described here with the ->lockForUpdate() method and using DB::transaction()s to make sure that only one of these updates happens at a time.
I would also suggest you look into double entry accounting to ensure that even if your code somehow allows another one of these race conditions that you have an audit log that you can refer back to, to balance your books.
@nexxai I am new to laravel and I admit I didn"t know about this lock function. so I have a few questions:
If I use lockForUpdate() when getting the data to populate the update form, is it auto-unlocked when later the Model->update() is fired or it should be done mnually?
Also, isn't using the transactions used by default in Laravel 10?
Can I use lockForUpdate() in the commonEditData()?
And then DB::transaction() and DB::commit() in commonUpdateData() or it is done automatically by Laravel?