JPA 2.1版带来了一种新的方式来处理持久性上下文与当前JTA事务以及资源管理器之间的同步。 术语资源管理器来自Java事务处理API ,它表示操纵一个资源的组件(例如,使用JDBC驱动程序操纵的具体数据库)。 默认情况下,容器管理的持久性上下文的类型为SynchronizationType.SYNCHRONIZED ,即,该持久性上下文自动加入当前的JTA事务,并将对持久性上下文的更新传播到基础资源管理器。

通过创建新类型为SynchronizationType.UNSYNCHRONIZED的持久性上下文,将禁用事务的自动连接以及将更新传播到资源管理器。 为了加入当前的JTA事务,代码必须调用EntityManager joinTransaction()方法。 这样,EntityManager的持久性上下文将在事务中登记,并为后续通知注册。 提交或回滚事务后,持久性上下文将离开事务,并且不会附加到任何其他事务,直到再次为新的JTA事务调用joinTransaction()方法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

JPA 2.1:不同步的持久性上下文相关推荐

  1. 1.0jpa 2.0_JPA 2.1:不同步的持久性上下文

    1.0jpa 2.0 JPA 2.1版带来了一种新的方式来处理持久性上下文与当前JTA事务以及资源管理器之间的同步. 术语资源管理器来自Java事务处理API ,它表示操纵一个资源的组件(例如,使用其 ...

  2. 1.0jpa 2.0_Java EE 7之前版本替代JPA 2.1非同步持久性上下文

    1.0jpa 2.0 Java EE 7中的非同步持久性上下文 JPA 2.1引入了非同步持久性上下文的概念,该概念允许对JPA实体管理器的刷新进行细粒度控制,即通过显式调用EntityManager ...

  3. Java EE 7之前版本替代JPA 2.1的非同步持久性上下文

    Java EE 7中的非同步持久性上下文 JPA 2.1引入了非同步持久性上下文的概念,该概念允许对JPA实体管理器的刷新进行细粒度控制,即通过显式调用EntityManager#joinTransa ...

  4. hibernate自动配置_Hibernate自动冲洗的黑暗面

    hibernate自动配置 介绍 既然我已经描述了JPA和Hibernate刷新策略的基础知识 ,我就可以继续阐明Hibernate的AUTO刷新模式的令人惊讶的行为. 并非所有查询都会触发会话刷新 ...

  5. 休眠自动冲洗的黑暗面

    介绍 既然我已经描述了JPA和Hibernate刷新策略的基础知识 ,我就可以继续阐明Hibernate的AUTO刷新模式的令人惊讶的行为. 并非所有查询都会触发会话刷新 许多人会认为Hibernat ...

  6. jpa一级缓存和二级缓存_了解一级JPA缓存

    jpa一级缓存和二级缓存 我敢打赌,每个Java开发人员至少都听说过L1(又名EntityManager或Session)缓存. 但是您的理解水平足够好吗? 如果不确定,请考虑阅读这篇文章. 首先,我 ...

  7. jpa 查询 列表_终极JPA查询和技巧列表–第2部分

    jpa 查询 列表 这一部分是该系列文章的第一部分 . JPA:NamedQuery,使用日期查询,有关getSingleResult方法的警告 为了避免重复查询代码,提高性能并简化维护查询,我们可以 ...

  8. jpa 查询 列表_终极JPA查询和技巧列表–第3部分

    jpa 查询 列表 在阅读第三部分之前,请记住本系列的第一部分和第二部分 JPA:通过查询创建对象 JPA允许我们使用所需的值在查询内创建对象: package com.model;public cl ...

  9. JPA /休眠刷新策略初学者指南

    介绍 在我之前的文章中,我介绍了实体状态转换 对象关系映射范例. 当刷新当前持久性上下文时,所有管理实体状态转换都将转换为关联的数据库语句. Hibernate的刷新行为并不总是像人们想象的那么明显. ...

最新文章

  1. python内建作用域_为什么 Python 的类不构成作用域(scope)?
  2. java条件操作_关于java:条件为true时,从头开始执行各种操作的顺序
  3. linux中mkswap命令使用方法,mkswap命令_Linux mkswap 命令用法详解:建立和设置SWAP交换分区...
  4. 开源游戏地图编辑器 Mepper
  5. supermap iserver端口介绍
  6. python输出字符_python输出字符
  7. 2019有的图纸打印出来看不清楚_CAD图纸打印出来后很多CAD文字消失了怎么办?...
  8. 洛谷——P2415 集合求和
  9. AutoMapper搬运工之初探AutoMapper
  10. POJ1088(dp)
  11. uniapp-蓝牙模块封装
  12. 人工智能原理与方法作业1
  13. mysql unzip下载_zip unzip 命令
  14. 神经网络用于控制的优越性,神经网络的稳定性
  15. 小程序内嵌的H5页面如何跳转到其他小程序?
  16. maya导入abc动画_如此导出ABC缓存,扩展秘籍(二)!!!
  17. 华为无线网卡无服务器,联通华为无线上网卡连接时连接被终止解决方法 - 小众知识...
  18. 【网络流量识别技术之初级入门篇】
  19. 3GPP最新提案查询方法
  20. ADB修改mumu模拟器分辨率

热门文章

  1. springmvc中报错Request processing failed;
  2. 2小时学习Spring Boot 2019版本 代码一样推送至github上面去
  3. antd vue表单上传文件_vue+axios+antD的上传图片踩坑
  4. 怎么看cudnn的版本好_针对此次版本削弱,怎么用好嫦娥!
  5. 完整的MIME类型列表
  6. spring(2)装配Bean
  7. Integer和Int的比较,谈谈拆卸和装箱
  8. 有序数组中查找第一个比target大的数
  9. 骆驼(camel)命名法_Apache Camel 3 –骆驼核心vs骆驼核心引擎(较小的核心)
  10. javafx如何带菜单_JavaFX技巧30:带有DropShadow的ScrollPane