如何用Spring框架模块化Hibernate SessionFactory(上)

日期: 2011-11-20 作者:Ding Yun博士Karsten Klein翻译:杨华军 来源:TechTarget中国 英文

应用模块化方法概要   在本文中,我们将对用Spring和Hibernate进行模块化和事务管理的方案进行阐述。类似于OSGi JPA服务规范,它允许每一个企业应用的持久层模块拥有自己独立的配置,模块化的SessionFactory。   因此,实体类和一个模块相关的SessionFactory配置跟其他模块都是相互隔离的。模块化一方面迫使模块之间互相隔离,而另一方面呢,它又增加了在事务范围之内进行协调的需要。

  为了避免XA协议分布式事务处理的成本和复杂性,我们从两方面拓展了Spring事务管理:SessionFactory交换以及事务同步。一个单个的非JTA的事务管理器贯穿了所有与逻辑事……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

应用模块化方法概要

  在本文中,我们将对用Spring和Hibernate进行模块化和事务管理的方案进行阐述。类似于OSGi JPA服务规范,它允许每一个企业应用的持久层模块拥有自己独立的配置,模块化的SessionFactory。

  因此,实体类和一个模块相关的SessionFactory配置跟其他模块都是相互隔离的。模块化一方面迫使模块之间互相隔离,而另一方面呢,它又增加了在事务范围之内进行协调的需要。

  为了避免XA协议分布式事务处理的成本和复杂性,我们从两方面拓展了Spring事务管理:SessionFactory交换以及事务同步。一个单个的非JTA的事务管理器贯穿了所有与逻辑事务相关的会话工厂,而这个逻辑事务则是跨越了不同的模块边界的。在交易同步的概念下,我们利用共享数据库连接实现了“共享事务资源”模式,以此来保证逻辑事务的原子性。

  在对全局SessionFactory进行模块化之后,尽管SessionFactory交换和事务同步导致了过载,但是我们测出事务的吞吐量得到了提升(3-5%)。此外,模块内部会话工厂现在可以根据特定的模块需求独立地进行配置和优化,这在过去是不行的。我们还概要解释了OSGi JTA事务服务规范及OSGi JPA服务规范所倡议的模块化方案,并指出其与我们的方案有何共同点。

  本文的目的旨在对我们所选方案进行深入分析。以便得到反馈和评论。我们相信该方案在领域驱动概念领域的力量,希望就此话题发起一场讨论。

  模块化及事务管理

  在大规模应用开发中,模块化是一个广为采纳的概念。通常,此类应用会被结构为若干的模块或包(此处所述的模块和包可互换),这些模块中的每一个都负责特定领域的一个功能。这一类模块化也被称为垂直模块化,与此相对应(颗粒度有点粗)的是水平模块化,即应用被分割成不同的技术层(如持久层)。

  Transactions是企业应用的关键组件。当一个交易牵涉到多个模块的时候,每一模块的输出都必须进行协调,以便其相结合的输出能满足事务原子性的要求。事务要么是成功—即所有涉及的模块均成功的情况下,要么只要有一个模块失败就得 回滚。我们把跨模块的事务定义为逻辑事务,该事务跨越了多个持久模块。

  模块化和事务管理密切相关。一方面,模块化令模块之间互相隔离,而另一方面呢,它又增加了在事务范围内进行协调的成本和复杂性。在本文中,我们阐述了利用Spring和Hibernate进行模块化及事务管理的方案。并对OSGi服务平台企业规范 [3]所倡议的方案进行概要描述,然后指出此二者的相似之处。

  利用Spring和Hibernate进行模块化

  尽管对企业应用的支持在不断提升,m将已有企业应用移植到Spring DM或者OSGi上面仍是件非常具有挑战性的工作,由于许多不可预见的问题,引发故障解决类的加载,如ClassNotFoundExceptions或LinkageErrors [4]。因此,我们决定坚持采用纯Spring和Hibernate,打通了一条长长的通往基于OSGi进行部署的移植之路。

图1利用特定模块会话工厂进行的垂直模块化

图1利用特定模块会话工厂进行的垂直模块化

  为了进行模块隔离,每一模块的实体类和相关持久配置都保持在自己模块的边界内。这个跟领域驱动设计 [5]的概念是一致的 。既然会话工厂充当了Hibernate中的持久层配置的角色,那么共享、全局的,允许每一持久层模块都拥有各自独立配置、与模块相关的SessionFactory(参见图1,SFA代表了模块A的SessionFactory)的需要也就免去了。

  在一个逻辑事务里面使用多个会话工厂会引发事务管理方面的挑战。在Spring中,当应用启动的时候,一个事务管理器正好是跟一个SessionFactory或一个数据源配置在一起的。一般情况下,这种绑定是静态的,此后不再改变。对此,我们处理跨模块事务有以下的替代方案:

  • 使用多个事务管理器,将其中的每一个都各自捆绑到一个SessionFactory上。
  • 结合XA协议使用一个支持分布式事务的JTA事务管理器。
  • 释放与单个SessionFactory的静态绑定,允许事务管理器绑定到此逻辑事务范围内的不同的会话工厂上。

  鉴于XA协议两阶段提交 潜在的成本和复杂性,我们很快放弃了前两种替代方案。由于应用的大多数模块都共享供一个数据源,其所增加的成本和复杂性完全是没有必要的。

  让我们来看一看第三个选项,利用单个非JTA事务管理器的方案。应用启动时,在没有静态绑定到单个SessionFactory的情况下,事务管理器横跨了跨模块的事务所涉及的所有会话工厂。然而,在一个应用的全部模块只有一个SessionFactory的假设下,Spring为每一个参与跨模块事务的SessionFactory都创建了一个新的Spring事务。

  因此,一个逻辑跨模块事务被映射到了多个Spring事务上。该方案仍旧需要对这些Spring事务之间进行协调。在有和没有XA的情况下实现分布式事务存在着不同的模式[2]。出于简化和更高吞吐量的目的,我们选择了“共享事务资源”的模式,该模式不需要XA的参与,确保所有资源都得到统一资源的同步或支持,在我们的这个案例中这个资源是指连接而非Hibernate会话。

  我们从两方面延伸了Spring的事务管理概念:SessionFactory交换以及连接级的事务同步。SessionFactory的概念使得事务管理器贯穿了跨模块事务所涉及的会话工厂。而事务同步的概念则实现了共享事务资源模式。

  在《如何用Spring框架模块化Hibernate SessionFactory(下)》种,我们将介绍SessionFactory交换、事务同步、逻辑事务注解、模块化会话工厂的优点、OSGi的模块化。

相关推荐