1.0jpa 2.0_JPA 2.1:不同步的持久性上下文
1.0jpa 2.0
JPA 2.1版帶來了一種新的方式來處理持久性上下文與當前JTA事務以及資源管理器之間的同步。 術語資源管理器來自Java事務處理API ,它表示操縱一個資源的組件(例如,使用其JDBC驅動程序操縱的具體數據庫)。 默認情況下,容器管理的持久性上下文的類型為SynchronizationType.SYNCHRONIZED ,即,該持久性上下文自動加入當前的JTA事務,并將對持久性上下文的更新傳播到基礎資源管理器。
通過創建新類型為SynchronizationType.UNSYNCHRONIZED的持久性上下文,將禁用事務的自動連接以及將更新傳播到資源管理器。 為了加入當前的JTA事務,代碼必須調用EntityManager joinTransaction()方法。 這樣,EntityManager的持久性上下文將在事務中登記,并為后續通知注冊。 提交或回滾事務后,持久性上下文將離開事務,并且在新的JTA事務再次調用joinTransaction()方法之前,持久上下文不會附加到任何其他事務。
JPA 2.1之前,一個可以實現與一個跨越多個方法調用的對話@Stateful由亞當邊描述會話Bean 在這里 :
@Stateful @TransactionAttribute(TransactionAttributeType.NEVER) public class Controller {@PersistenceContext(type = PersistenceContextType.EXTENDED)EntityManager entityManager;public Person persist() {Person p = new Person();p.setFirstName("Martin");p.setLastName("Developer");return entityManager.merge(p);}public List<Person> list() {return entityManager.createQuery("from Person", Person.class).getResultList();}@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)public void commit() {}@Removepublic void remove() {} }持久性上下文的類型為EXTENDED ,因此,其生存期比它所附加的JTA事務的壽命長。 由于持久性上下文默認也是SYNCHRONIZED類型,因此它將在調用任何會話bean的方法時自動加入正在運行的任何事務。 為了防止大多數Bean方法發生這種情況,注釋@TransactionAttribute(TransactionAttributeType.NEVER)告訴容器不要為該Bean打開任何事務。 因此,方法persist()和list()無需事務即可運行。 對于方法commit()此行為是不同的。 在這里,注釋@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)告訴容器在調用該方法之前創建一個新事務,因此Bean的EntityManager將自動加入該事務。
使用新的SynchronizationType.UNSYNCHRONIZED類型,可以如以下清單所示重寫上面的代碼:
@Stateful public class Controller {@PersistenceContext(type = PersistenceContextType.EXTENDED,synchronization = SynchronizationType.UNSYNCHRONIZED)EntityManager entityManager;public Person persist() {Person p = new Person();p.setFirstName("Martin");p.setLastName("Developer");return entityManager.merge(p);}public List<Person> list() {return entityManager.createQuery("from Person", Person.class).getResultList();}public void commit() {entityManager.joinTransaction();}@Removepublic void remove() {} }現在,EntityManager不會自動加入當前事務,我們可以省略@TransactionAttribute批注。 在我們明確加入之前,任何正在運行的事務都不會對EntityManager產生影響。 現在,這是在commit()方法中完成的,甚至可以基于某些動態邏輯來完成。
為了測試上面的實現,我們利用了一個簡單的REST資源:
@Path("rest") @Produces("text/json") @SessionScoped public class RestResource implements Serializable {@Injectprivate Controller controller;@GET@Path("persist")public Person persist(@Context HttpServletRequest request) {return controller.persist();}@GET@Path("list")public List<Person> list() {return controller.list();}@GET@Path("commit")public void commit() {controller.commit();}@PreDestroypublic void preDestroy() {} }此資源提供了持久化人員,列出所有持久化人員并提交當前更改的方法。 當我們將使用有狀態會話Bean時,我們使用@SessionScoped注釋資源,并讓容器注入Controller Bean。
在將應用程序部署到某個Java EE容器后,通過調用以下URL,一個新人員將被添加到非同步的持久性上下文中,但不會存儲在數據庫中。
http://localhost:8080/jpa2.1-unsychronized-pc/rest/persist即使調用list()方法也不會返回新添加的人員。 只有最終通過調用commit()將持久性上下文中的更改與基礎資源同步,才將insert語句發送到基礎數據庫。
結論
持久性上下文的新UNSYNCHRONIZED模式使我們可以通過狀態會話bean的多個方法調用來實現對話,并且可以靈活地根據我們的應用程序邏輯動態地加入JTA事務,而無需任何注釋魔術。
- PS:源代碼可從github獲得 。
翻譯自: https://www.javacodegeeks.com/2015/03/jpa-2-1-unsynchronized-persistence-context.html
1.0jpa 2.0
總結
以上是生活随笔為你收集整理的1.0jpa 2.0_JPA 2.1:不同步的持久性上下文的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ios怎么备份
- 下一篇: @namedqueries_在@Name