Say my web server receives two simultaneous requests.
It will handle each request in a separate thread.
It will create a JPA entity manager for each thread.
Now let’s say each thread requests the same database row. Say I have a table called Cars. I have a car with id = 5. I do a find for a car with id = 5 in both threads.
So I now have two separate objects representing the same entity.
Now let’s say I update the gasLevel of the car in thread 1. If I get the gasLevel in thread 2, will I get the new gasLevel set by thread 1?
No, you won’t, because as you said, you have two different instances of the entity. If they both update the gasLevel to a different value, then the last commit will win.
That’s one of the reasons to implement optimistic locking, using a version field annotated with @Version: the last commit will fail because some other transaction has updated the value between the moment the entity was loaded and the moment its new state is flushed.
Note that even if thread 1 reads the value (7), changes it to 8, flushes, and thread2 then reads the value, thread 2 will still see 7 in the default case, because the default case is to use the READ_COMMITTED isolation level. This means that one transaction only sees the data that has been committed by other transactions. This depends on the database, though. HSQLDB for example only supports READ_UNCOMMITTED.