How JPA manage entities accross all same application instances?

How JPA manage entities accross all same application instances?



I have some confusing things about JPA.



As far as I know, JPA has persistence context(aka. L1 cache) and It manages all entities for persistence. and It manages entity with the below process.

1. when the find query occurs, there is no entity in context, so entity manager request data to the database

2. save the result as entities in persistence contentext.

3. after this, when the query occurs, persistence query return memory entities if they have.



But in 3rd, It is quite confusing how it works in multiple instances environment. I think, in multiple application instances, It can't ensure same entity data across all instances.



Let's assume that there are 2 instances of JPA application.(all instances are same logic for load balance). table has 2 column, one is id, primary key, and the other is name varchar.



There are a row which is id=1, name="foobar"



"instance A" generate entity which is ID equal 1 from database by user select query.

also "instance B" generate same entity which is ID equal 1 from database by user select query.

and then "instance A" update entity which is ID=1 to name="blahblah" by user update query.



After enough time later with no query to both instances, if update query which is "update name set newname from table where name=blahblah" occurs in "instance B", I'm confused, It has already the entity and its name may not updated to "blahblah". so How does the last update query work in JPA?



EDIT
I realized that my question is not clear. Because JPA execute DB query to DBMS when the transaction was commited, Usually there is no problem how many applications are.



To tell you why I ask this, let's assume that there is below code.


void updateEntities()
entityManager.getTransaction().begin();
List<MyEntity> entities = dao.findAll(); // point1
for (MyEntity e : entities)
e.setValue(e.getValue() + 100); // point2

entityManager.getTransaction().commit();


List<MyEntity> findMyEntities()
return dao.findAll(); // point3



Two instance which has above code block in their code(both are same code instances for load balancing). (and the number of entities are enough number for RAM.)



when A instance generate entities in memory when findMyEntities method was called by client query.

then next query was occured by client, then the request reached to instance B, and the instance B also generated all entities in memory.
and then update query reached to instance A and instance executed updateEntities and all entities in memory of instance A were updated.

but in this time, There are difference between instance A's cached entities and instance Bs cached entities. But instance B may not be able to know the data was updated or not.


A instance


findMyEntities


instance B


instance B


instance A


instance A


instance A


instance B


instance B



So I wondered when the update query is occured to instance B after above situation, I believed like below


instance B


updateEntities



Is it correct?





I believe that JPA "knows" when a refresh on the underlying entity is necessary, i.e. it knows when it has to refresh from the database.
– Tim Biegeleisen
Aug 31 at 3:16





If you have 2 unconnected applications then JPA (in app1) will not know of any updates that have happened in app2, unless they are sharing the same (external) L2 cache of course. But then the log would tell you where objects are coming from
– Billy Frost
Aug 31 at 7:57




3 Answers
3



This is about transaction isolation and lock. If you want to see changes committed by other transactions, refresh(entity) is needed. JPA does not know about changes committed by other transactions.



Class of the bean, is usually marked with:



@Stateless without status, that is, it does not save the state even if another bean requests the same information.



You can read:



https://www.tutorialspoint.com/ejb/ejb_stateless_beans.htm



@StateFul with status, will save the state, and it will not change until the bean ends the transaction.



You can read:



https://www.tutorialspoint.com/ejb/ejb_stateful_beans.htm



And read this:



https://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html



In addition to this, you can have the methods(through the EntityManager and EntityTransaction):



rollback



flush



refresh



commit



setFlushMode () that can have two values, AUTO and COMMIT



See an example:


EntityManager em = ....
EntityTransaction et = em.getTransaction();
et.begin();
try
em.persist(someObject);
et.commit();


et.rollback();



Finally you can specify the type of transaction you want to use in your bean, these can be:



MANDATORY



REQUIRED



REQUIRES_NEW



SUPPORTS



NOT_SUPPORTEED



NEVER



To use this attribute:


@TransactionAttribute(TransactionAtributeType.NEVER)
public float division(float a,float b)
return (a/b);



This question is originated from my misunderstanding about JPA L1 cache life.



The L1 cache is invalidated when the transaction was committed or client request was over(in OSIV).



So In my point, the L1 cache is not shared with thread or process.

It is valid only a same transaction or same request in OSIV.



So there is no problem if the instances are multiple or not.



I appreciate someone who answered the stupid question.



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Some of your past answers have not been well-received, and you're in danger of being blocked from answering.



Please pay close attention to the following guidance:



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)