[英]How JPA manage entities accross all same application instances?
關於JPA,我有些困惑。
據我所知,JPA具有持久性上下文(也稱為L1緩存),並且它管理所有實體以實現持久性。 並且通過以下過程管理實體。
1.發生查找查詢時,上下文中沒有實體,因此實體管理器向數據庫請求數據
2.將結果另存為持久性contentext中的實體。
3.之后,當查詢發生時,持久性查詢將返回內存實體(如果有)。
但是在第三版中,它在多個實例環境中的工作方式非常令人困惑。 我認為,在多個應用程序實例中,它不能確保所有實例中的實體數據相同。
假設有兩個JPA應用程序實例(所有實例都是相同的負載均衡邏輯)。 該表有2列,一個是id,主鍵,另一個是名稱varchar。
有一行是id = 1,name =“ foobar”
“實例A”通過用戶選擇查詢從數據庫生成ID等於1的實體。
“實例B”還通過用戶選擇查詢從數據庫生成ID等於1的相同實體。
然后通過用戶更新查詢將ID = 1的“實例A”更新實體命名為“ blahblah”。
經過足夠的時間后,沒有對兩個實例進行查詢,如果在“實例B”中發生了更新查詢,即“從名稱= blahblah的表中的表中更新名稱設置新名稱”,我很困惑,它已經有實體,並且其名稱可能沒有更新為“等等”。 那么最后更新查詢在JPA中如何工作?
編輯我意識到我的問題不清楚。 因為提交事務時JPA對DBMS執行DB查詢,所以通常沒有多少應用程序的問題。
為了告訴您為什么要問這個,讓我們假設下面有代碼。
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
}
在其代碼中具有上述代碼塊的兩個實例(兩個都是用於負載平衡的相同代碼實例)。 (並且實體的數量足以容納RAM。)
當客戶端查詢調用findMyEntities
方法時A instance
在內存中生成實體。
然后客戶端進行下一個查詢,然后請求到達instance B
, instance B
也生成了內存中的所有實體。 然后到達instance A
更新查詢和實例執行的updateEntities以及instance A
內存中的所有實體均被更新。
但是這次, instance A
的緩存實體和instance B
的緩存實體之間有所不同。 但是instance B
可能無法知道數據是否已更新。
所以我想知道在上述情況之后何時對instance B
進行更新查詢,我相信像下面這樣
updateEntities
方法。 這是正確的嗎?
這是關於事務隔離和鎖定的。 如果要查看其他事務提交的更改,則需要refresh(entity)。 JPA不知道其他事務提交的更改。
Bean的類,通常標記為:
@Stateless沒有狀態,也就是說,即使另一個bean請求相同的信息,它也不會保存狀態。
你可以閱讀:
https://www.tutorialspoint.com/ejb/ejb_stateless_beans.htm
具有狀態的@StateFul將保存狀態,並且在bean結束事務之前它不會改變。
你可以閱讀:
https://www.tutorialspoint.com/ejb/ejb_stateful_beans.htm
並閱讀以下內容:
https://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html
除此之外,您還可以使用方法(通過EntityManager和EntityTransaction):
回滾
紅暈
刷新
承諾
setFlushMode()可以具有兩個值:AUTO和COMMIT
看一個例子:
EntityManager em = ....
EntityTransaction et = em.getTransaction();
et.begin();
try{
em.persist(someObject);
et.commit();
}
et.rollback();
最后,您可以指定要在bean中使用的事務類型,可以是:
強制性
需要
REQUIRES_NEW
SUPPORTS
NOT_SUPPORTEED
決不
要使用此屬性:
@TransactionAttribute(TransactionAtributeType.NEVER)
public float division(float a,float b){
return (a/b);
}
這個問題源於我對JPA L1緩存壽命的誤解。
當事務已提交或客戶端請求結束時(在OSIV中),L1緩存無效。
因此,就我而言,L1緩存不與線程或進程共享。
它僅對OSIV中的同一事務或相同請求有效。
因此,實例是否多個都沒有問題。
我感謝有人回答了這個愚蠢的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.