作者:狂放不羁
网址:http://yuquan.blog.51cto.com

>>>转载请注明出处!<<<

接着上篇“J2EE事务并发控制策略总结”,今天我接着写一下持久化上下文的传播问题。
目前持久层框架都有一个持久化上下文的概念,下面以比较流行的hibernate以及JPA来做一总结。
     如果我们采用OO的方式开发系统,那么势必为了减低耦合,增加内聚,我们会通过细粒度的类来实现业务功能,那么这样就产生了一个问题,如何将持久化上下文在不同的类(这里面其实就是Dao类或者DDD里面的repository)中传播,比如传统的开发方式中,一个service里通过不同的Dao来访问数据库,那么怎么保证不同的Dao类中用的session以及以及与session对应的持久化上下文是同一个呢?这就涉及到了持久化上下文如何传播的问题。下面以我熟悉的hibernate以及JPA来来说明一下,在hibernate中,根据采用的底层事务的不同,需要采用不同的策略来实现:

1 Hibernate中持久化上下文的传播

1.1 采用jdbc事务

此时hibernate通过Threadlocal将当前的session与当前的线程绑定在一起,这样以来只要是同一个线程中的调用,那么获得的session都是同一个,具体来说就是配置hibernate.current_session_context_class属性为thread,这样以来hibernate内部就会通过CurrentSessionContext接口的实现类ThreadlocalSessionContext通过threadlocal来将session和当前线程绑定在一起。当调用SessionFactory的getCurrentSession()方法,返回的就是与当前线程绑定的session,从而解决了持久层上下文传播的问题。

1.2 采用JTA事务

此时hibernate内部是将当前的session以及对应的持久化上下文绑定到了全局的JTA事务上,这样以来我们通过sessionFactory的getCurrentSession()方法获得的就是与当前的JTA事务绑定的session.具体一点就是配置属性hibernate.current_session_context_class为jta,这样以来hibernate内部就是通过CurrentSessionContext接口的实现类JTASessionContext来将session与当前的JTA全局事务绑定在一起,因此当我们通过sf.getCurrentSessionContext()来获取session时,获得的就是与当前的JTA绑定到一起的session.
但是在此种情况下,需要特别注意一个问题:不能同时使用hibernate的Transaction接口与getCurrentSession(),因为当前的session是绑定到全局JTA事务中的,如果通过session.beginTransaction()来开始事务,这说明以前没有事务,既然没有事务存在,我们的session又是怎么绑定到全局JTA事务上的呢?所以一定要注意:当使用JTA事务,并且用了getCurrentSession()的方法时,一定不要用hiernate的native transaction 接口。但是我们如果我们用openSession(),那么就可以通过通过hibernate的native Transaction接口来控制JTA事务。
最后还需要弄清楚一点,Hibernate中还有一种绑定持久化上下文的方法,那就是通过设置hibernate.current_session_context_class属性为managed,hiberante内部就是通过CurrentSessionContext接口的实现类ManagedSessionContext来绑定的。在此种情况下主要是为了实现会话,会话在hibernate中的实现在下面介绍。

2 JPA中持久化上下文的传播

JPA中持久化上下文的传播根据采用不同的事务模型而不同,下面分别来说明:

2.1 采用resource-local事务模型

如果采用resource-local事务模型,此种情况也就是在非J2EE应用服务器的支持下使用。那么我们的持久化上下文的生命周期是与当前的EntityManager绑定到一起的,所以我们可以在不同的类中传播相同的EntityManager实例来达到传播事务上下文的传播。

2.2 采用JTA事务模型

在此种模型下面,我们有EJB容器的支持,持久化上下文的传播是借助于事务上下文来传播的,在说明如何传播前首先要明确EJB组件中两种不同的事务上下文的生命周期:
对于stateless session bean,持久化上下文的生命周期是与当前的系统事务一致的,这也就是无状态会话bean的事务型的持久化上下文,每当事务结束,持久化上下文也就结束了,所有持久化对象也就变为了脱管的(detached).
对于statefull session bean,持久化上下文的生命周期是与当前的有状态会话bean一致的,只有当有状态的会话bean从系统中移除的时候,持久化上下文才关闭,这也就是有状态会话bean的扩展的事务上下文。
搞清楚了这两种不同的事务上下文的生命周期以后,我们来说一下持久化上下文如何传播的问题。持久化上下文是通过当前系统事务来传播的,当一个EJB组件调用另一个EJB组件的时候,如果两个EJB组件的事务范围是一样的,那么持久化上下文就会传播,下面分几种情况来说明:
无状态会话bean之间调用:此时如果两个无状态会话bean在同一个事务中调用,那么持久化上下文就是同一个,通过当前事务来传播。
有状态会话bean调用无状态会话bean:此种情况下如果两者在同一个事务中,那么有状态会话bean的扩展的事务上下文会传播到无状态会话bean里,其实还是通过事务来传播。但是如果被调用的无状态会话bean不支持事务的话(事务属性设置为not support 或者never),那么此时持久化上下文不能传播(JPA规范规定扩展的持久化上下文是不能传播到无事务的stateless session bean)。
有状态会话bean之间调用:此时无论两个有状态会话bean是否支持事务,那么扩展的持久化上下文都会传播,此时就不是通过系统事务来传播的,而是通过statefull session bean的实例来传播(但是此时一定要注意有状态会话bean必须是通过容器注入的或者显示通过JNDI查找)。
    无状态的会话bean调用有状态会话bean:一个有事务范围的持久化上下文的stateless session bean调用一个statefull session bean会引发一个错误,因为当前的事务上下文不能传播)
综上所述,EJB之间的持久化上下文传播是通过我们的系统事务来传播的,如果EJB不支持事务(事务属性设置为not support或者never)),那么持久化上下文就不会传播,但是对于扩展的持久化上下文,是通过statefull session bean来传播的,即使没有事务也可以传播,下篇的如何实现会话会再谈到这个问题。
前面说的是关于持久化如何在持久层的不同的类之间传播的问题,其实无外乎就是通过当前的线程和当前的系统事务来传播,不过对与statefull session bean的扩展的持久化上下文,传播是通过实例来传播的,在下面的实现会话的讨论中,我还会说到这个问题。当我们掌握了原理的时候,遇到一些问题的时候,我们就会很快找到解决方案。
未完待续。。。
下篇“J2EE持久层如何实现会话”

转载于:https://blog.51cto.com/yuquan/360724

J2EE持久层持久化上下文传播总结(续)相关推荐

  1. 轻量级J2EE持久层解决方案,MiniDao-PE版 1.5.4【版本发布】

    MiniDao-PE精简版(轻量级持久层) MiniDao-PE是一种轻量级J2EE持久层解决方案,类似mybatis持久层的SQL方式,可以轻松集成Hibernate项目,事务统一管理,解决了Hib ...

  2. MiniDao 比Mybatis还灵活实用的J2EE 持久层轻量级解决方案

    MiniDao 详细地址:http://zhangdaiscott.github.io/MiniDao/ 源码下载地址:http://code.google.com/p/jeecg/downloads ...

  3. 对持久层、持久性、持久化的讨论

    序: 关于持久层.持久性.持久化这几个名词,对我们平时应该是很常见的,其实看多了也大概知道了其中的意思,但是如果让我详细的介绍她们的精确定义,可能就不太容易了,下面我就详细介绍一下,这三个词的精确定义 ...

  4. 在 SCA Module 中使用 iBATIS 框架实现数据持久层

    在完成 SCA Module 建模后用 Java 对象进行实现时,采用 Hibernate 和采用 iBATIS 实现 SCA Module 的数据持久层,目的都是为 SDO 提供数据访问服务并加快 ...

  5. Java软件开发:自定义MyBatis持久层框架

    自定义MyBatis持久层框架 1 框架概述 1.1 什么是框架 1.2 框架要解决的问题 1.3 软件开发的分层的重要性 2 MyBatis框架 3 JDBC编程 3.1 JDBC程序的回顾 3.2 ...

  6. 持久层的EAO颗粒封装

    设计一个灵活性高.扩展性好的软件产品不是一件容易的事情. 在面向对象的世界里,解耦才是真正的宗旨所在,只有充分恰当的通过抽象.封装.继承和多态才能达到解耦的宗旨,才有可能做好一款灵活性高.扩展性好的软 ...

  7. 在 SCA Module 中使用 Hibernate 框架实现数据持久层

    一.背景 SCA(Service Component Architecture)作为服务组件体系结构,将所有的集成构件都描述为具有定义明确的接口的服务组件.SCA 还引入了模块的概念,它将服务组件集中 ...

  8. JAVA表示层,业务层,持久层的框架分别有哪些

    JAVA表示层,业务层,持久层的框架分别有哪些 1.表示层 JSP,Freemark,Velocity, 2.控制层 Struts,Struts2 3.持久层 Hibernate.Mybatis.My ...

  9. SSH、SSM三种框架及表示层、业务层和持久层的理解

    Struts(表示层)+Spring(业务层)+Hibernate(持久层) SSH:Struts(表示层)+Spring(业务层)+Hibernate(持久层) Struts:Struts是一个表示 ...

最新文章

  1. .net autofac Web Forms
  2. 微软云计算介绍与实践(实践之十七)
  3. IBM发布全球首台商用量子计算机
  4. 自定义Title(可以实现类似于携程网上价格的显示方式)
  5. 关于Jsoup解析https网页的问题
  6. 4个在2020年持续发展的数据中心冷却趋势
  7. java设计模式之外观模式(门面模式)
  8. 黑客必须了解的网络知识
  9. js获取字符串的字节数
  10. pytorch torch.nn.Embedding
  11. 10.15 sigstjmp以及siglongjmp函数
  12. 区块链项目开发最容易受区块链技术影响的行业
  13. Android RxJava
  14. GIS数据处理与应用开发一站式解决方案
  15. uploadify php 重命名,Uploadify_THINKPHP配置说明
  16. mkv格式提取文件方法
  17. 【fk_index】外键中有无索引的区别
  18. 前端设置div的显示与隐藏
  19. 谱密度,功率谱,能量谱密度
  20. 一起看TV:在电视上怎么下载软件?两个办法教你有效安装

热门文章

  1. json 和 pickle
  2. Android自定义View:MeasureSpec的真正意义与View大小控制
  3. 学好Linux必备知识
  4. 成熟的男人思考的东西
  5. LOJ#2085 循环之美
  6. APP启动原理,APPdelegate程序状态解析
  7. CentOS7上配置ELK
  8. Asp.net支持三种类型的cache[转]
  9. 1-6 数据查询(下)——复杂查询
  10. freebsd 编译核心