Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ghiath.dev's avatar

Race condition problem in a Laravel application

What is the best solution for the race condition problem in a laravel application?

Need to mention that lockForUpdate with DB transactions are used but still the problem is exists!

0 likes
15 replies
Snapey's avatar

Ideally, design out the race condition rather than trying to block it with locks and transactions. This means looking for ways to make the transaction atomic.

Snapey's avatar

not without knowing what problem you are facing

ghiath.dev's avatar

I am testing if there are multiple post requests for different endpoints which affect same models come together at the same time; It always makes conflicts with values.

let's say that there is 2 groups of requests, each group have an endpoint; The problem when testing that the one of them continues with old values even the other requests changed it.

Snapey's avatar

This happens if there is a lot of code between loading the post and saving the post. Best way to avoid this is to stop more than one person editing the same record at the same time. Its not a race condition issue.

Suppose I load the post(1) into my browser for edit,

You load post(1) into your browser for edit.

We both submit changes. as individual requests. The last person to save wins. Their content is saved and the one that saved first is overwritten. You cannot solve this with transactions and record locks.

ghiath.dev's avatar

The problem is not the code quantity, I want to ensure the correctness of model values no matter how much requests it received.

I am adding a sleep for one second just to produce the problem even more.

And for optimistic locking i don't see it convenient because as i saw about this approach it needs to save a version and that version will load in the browser and when sending the values i should send it back and check.

  • First of all: if 2 users load different views which relate to the same model and one of them changed it, in my app it is ok for the other to change it also but depending on the new values.(The process is adding amounts)
  • I am sending post requests without any views to load via HTTP async posts.
ghiath.dev's avatar

I am wondering why the lockForUpdate function not solving the problem!

I see that is the perfect use case for using it; even though the values goes wrong

jlrdw's avatar

@ghiath.dev I wouldn't worry about it, similar even happens here on forum. But so seldom.

Just my opinion.

jlrdw's avatar

@ghiath.dev Is this in an office where two users are editing the same record, should not be happening. Why would user 2 be editing what user 1 is editing?

Isn't customer dealing with only one representative.

Edit:

At the trucking company I worked at I believe something similar happened one time in 10 years. Two dispatchers just happened to edit the same load at the same time.

ghiath.dev's avatar

@jlrdw No, actually there is a chance that the customer makes a deposit himself or a user modifies its account .....

This happens like twice a month here.

jlrdw's avatar

@ghiath.dev Are you saying two different people is logged into the customers account at the same time?

Have you implemented authorization?

Who is the second person? Is it like a husband and wife who share the same account? Can you explain in more detail.

A race condition question came up about a year ago very similar, I did not save the link.

Edit:

Also see https://www.baeldung.com/cs/race-conditions

newbie360's avatar

@ghiath.dev

the lock useful when you doing some heavy operation inside transaction

mysql> begin;
mysql> select * from posts where id = 1 for update;
// ===> don't commit release the lock

open another terminal is can't query the same record, because the lock prevented read/write

PHP is stateless, thats not easy to handle this

but may be add a nullable column edit_expire_at in the table, first come first serve

the person A opened the form in the browser, set the edit_expire_at column to now()->addMinutes(5), if person A updated the record set back the column to null

person B opened the from, if the column not is null, you can notice a message the record has someone editing, render a normal page without form elements

may be this give you an idea https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event

Snapey's avatar

@ghiath.dev you will never solve this problem within the database. It needs an architectural change to the way your app works

Please or to participate in this conversation.