Hibernate学习_005_Hibernate 中关于SessionFactory、Session接口的理解

来源:互联网 发布:阿里云 流量收费标准 编辑:程序博客网 时间:2024/04/29 04:52

SessionFactory,Session作为Hibernate中的两个核心接口,Hibernate中几乎所有涉及到数据库的操作都必须通过这两个接口来实现。

简言之,SessionFactory 就是Session的工场,我们可以将SessionFactory看做是一个具体数据库在内存的映射,也可以将SessionFactory看作是一个具体数据库对应的连接池。而我们每次通过Session来操作数据,可以将Sesson看做一个从这个连接池取得的连接,当然,这个Session中不仅仅包含有一个Connection对象,还有很多其他对象。

关于理解SessionFactory和Session的难点在于,通过SessionFactory获取Session时所采用的方式的区别,一般通过SessionFactory有两个方法可以获取Session,getCurrnetSession()以及openSession()。这两个方法有以下几点明显的区别。

  1. openSession()方法每次都是获取的一个新的Session,并且使用完毕之后,这个session必须手动Close。而采用getCurrentSession()的时候,则每次都是从当前的上下文中获取Sesison,如果当前上下文中存在Session,就用当前的Session,否则就创建一个新的Session,并且这个Session是不需要手动的Close,而是会随着的事物的提交来关闭。
  2. 当我们通过OpenSession开启一个Session后,紧接着我们通过getCurrentSession()并不可以获取到那个使用openSession()方法打开的Session,这也许是这两个方法的实现类并不相同的原因。 而且在一个方法中,一般这两个方法不可以同时使用的。
  3. getCurrentSession(),一般用来确定事物的边界的时候,很有用,而使用openSession()方法每次取得的都是一个新的Session,也就是一个新的Connection,则没有办法实现维护事物的完整性。因为在同一个事务中,事务没有提交之前,getCurrentSession 取得的是同一个session,也就是还是在一个数据库连接中;提交之后,再次取得session是不同的session。自动提交。

在我们用getCurrentSession()获取Session的时候,是从上下文来获取Session的,当我们要指定这个获取Session的上下文时,只需要在Hibebrnate.cfg.xml中配置一个常量即可。如下代码所示:

<property name="current_session_context_class">thread</property> 
当current_session_context_class取值为Thread的时候,使用当前线程这个上下文来获取Session.也就是使用数据库本身的Connection来管理事物(将autoCommit设为false,如果流程一切正常,则commit,出现异常则rollback)

那么current_session_context_class取jta的时候是一个什么样的情况呢?现在我们设想这样一个情况,如果一个下单买东西的业务流程是这样的:首先这个流程要到数据库A(假设为MySql)去插入一条订单记录,随后还要在数据库B(假设为Oracle)中插入一条财务信息,此时很明显,针对每个数据都必须要有一个Connection对象来处理数据插入,那么此时如何保证事物完整性?这就是一种分布式的事物,此时就必须要通过JTA来解决。当使用jta来处理事物的时候,此时也要使用专门的驱动器类,这种数据库驱动叫做XADriver。而且还需要一个叫做事务管理器的中间件,这个中间件一般都是由ApplicationServer来提供,比如JBoss,WebLogic,但是我们常常使用的Tomcat并不提供JTA的支持,但当有Spring的支持后,Tomcat也是可以支持JTA事物的。

那么现在有一个问题,这些个中间件是如何保证事物的完整性的?上午Google了一把,一个解释是这样的:这个事物管理器中间件会记录每个Connection对具体数据库的操作,当所有操作完成后,一起提交,当这些个Connection中有一个失败,则以前Connection对数据库的操作全部rollback。



0 0
原创粉丝点击