Hibernate事务管理-HibernateTransactionManager-对hibernate session的管理

由于对SSH还停留在比较初级的应用水平上,今天在遇到一个疑惑时折腾了很久,具体问题是这样的,

有这么一个测试方法,

1     public static void test1() {
2         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml","daoContext.xml");
3         MgrManager mgr = (MgrManager)ctx.getBean("mgrManager");
4         List<EmpBean> emps = mgr.getEmpsByMgr("weblogic");
5         for (EmpBean empBean : emps) {
6             System.out.println(empBean.getEmpName());
7         }
8     }

其中的MgrManager是一个业务类, 提供一个根据名字查询员工的功能, 以上方法执行完全没有问题,

然后又有下面这个测试方法,

    public static void test2() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml","daoContext.xml");
        EmployeeDao empDao = (EmployeeDao)ctx.getBean("employeeDao");
        Employee emp = empDao.findByName("oracle");
        System.out.println(emp.getSalary());
    }

test1是使用业务类间接得查询数据库,得到结果,而test2是通过dao直接查询数据库, 但是test2始终报错说没有数据库session。

百思不得其解,按理说所有的bean是通过spring管理的,既然spring为业务类注入了sessionFactory, 为何dao类就没有呢?

然后通过手工在test2中写了如下代码,发现是可以通过测试的,

    public static void test3() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml","daoContext.xml");
        SessionFactory sf = (SessionFactory)ctx.getBean("sessionFactory");
        Session session = sf.openSession();
        List<Employee> emps = session.createQuery("select e from Employee e where e.name = ‘oracle‘").list();
    }

也就是说,问题不在于Spring容器中没有sessionFactory, 而是sessionFactory没有被open!那为什么test1的例子中的sessionFaction又open了呢?

看了配置文件半天,发现有这么关键的一行配置,

<aop:pointcut id="leePointcut" expression="bean(empManager)||bean(mgrManager))" />

另外,通过面向切面编程原理,Spring通过AOP机制为dao对象的数据操作提供事务管理,有如下配置,

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!-- 配置详细的事务语义 -->
    <tx:attributes>
        <!-- 所有以get开头的方法是只读的 -->
        <tx:method name="get*" read-only="true" />
        <!-- 其他方法使用默认设置 -->
        <tx:method name="*" />
    </tx:attributes>
</tx:advice>
<aop:config>
<!-- 配置一个切入点,用来匹配empManager和mgrManager两个Bean的所有方法的执行 -->
<aop:pointcut id="leePointcut" expression="bean(empManager)||bean(mgrManager)||bean(employeeDao)" />
<!-- 指定在leePointcut切入点应用txAdvice事务增强 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="leePointcut" />
</aop:config>

而下面这段配置是用来配置真正的事务管理类, 正是通过上面的切面配置, 将业务类与增强处理关联起来, 同时通过下面的事务管理类进行事务管理

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
    p:sessionFactory-ref="sessionFactory" />

那么重点就在上面的transactionManager这个bean了, 通过查询资料,初步了解到, HibernateTransactionManager这个类提供 sessionFactory的管理,为了实现数据同步,在HibernateTransactionManager内部会进行Hibernate session的open和close,并将打开的Hibernaate sesion关联到当前的Application session,在Application中则通过getCurrentSession方式获取争取的打开的Hibernate session,  从而解决某些方面的线程安全及同步问题。

由此可见,由于上面配置事务管理的切面类仅仅只是针对了业务类,即默认情况下只有业务类才用于打开的session, 由此可以理解上面的test2为什么报“没有打开的session”错误了。

针对上面的配置, 我做了如下修改,

<bean id="TestManager" class="service.impl.TestManagerImpl" p:empDao-ref="employeeDao"/>

果然修改之后test2就能正常执行了。

以上仅仅涉及非常非常小的问题, 主要还是对HibernateTransactionManager的理解不够深入造成的。

时间: 2024-10-21 02:57:52

Hibernate事务管理-HibernateTransactionManager-对hibernate session的管理的相关文章

Hibernate事务管理

Hibernate 是JDBC 的轻量级封装,本身并不具备事务管理能力.在事务管理层, Hibernate将其委托给底层的JDBC或者JTA,以实现事务管理和调度功能.      Hibernate的默认事务处理机制基于JDBC Transaction.我们也可以通过配置文件设定采用JTA作为事务管理实现: <hibernate-configuration>          <session-factory>                   ……               

[原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

1、Struts2和Hibernate的简单整合(带Session的管理方式)

1.关于数据库:是部门和员工的关系 关于entity和xx.hbm.xml的实现 Dept.class package cn.itcast.entity; import java.util.HashSet; import java.util.Set; public class Dept { private int deptId; private String deptName; // [一对多] 部门对应的多个员工 private Set<Employee> emps = new HashSe

Spring 事务源码分析——Hibernate篇

在Spring与Hibernate整合的时候,可以利用Spring的事务管理机制,为我们管理事务的开启.提交.回滚等操作.这样的方式极大的减少了我们的代码量,让我们只专注于业务代码的编写.在使用Hibernate的时候,每一个操作都要经历事务开启与提交这样的操作,他们在业务代码的周围,这样来看是不是就想到了AOP编程,把这部分代码抽取出来.没错,Spring正是这样做的,Spring的事务管理就是基于AOP的. 1 Spring的事务隔离与传播 Srping的事务定义了五个隔离等级(isolat

Spring+hibernate事务配置

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:task="http://www.springframework.org/schema/task"    xmlns:xsi="http://www.w3.org/2001/XMLSchem

Hibernate常用的接口和类---Session接口☆☆☆☆☆

一.特点 Session是在Hibernate中使用最频繁的接口.也被称之为持久化管理器.它提供了和持久化有关的操作,比如添加.修改.删除.加载和查询实体对象 Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心 Session是线程不安全的 所有持久化对象必须在 session 的管理下才可以进行持久化操作 Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久化操作的数据都缓存在 session 对象处 持久化类与 Sessi

JTA与Hibernate事务

Hibernate是JDBC的轻量级封装,本身并不具备事务管理能力,在事务管理层,Hibernate将其委托给底层的JDBC或者JTA,以实现事务的管理和调度. Hibernate的默认事务处理机制基于JDBCTransaction,也可以通过配置文件设定采用JTA作为事务管理实现: <hibernate-configuration> <session-factory> …… <property name = "hibernate.transaction.facto

hibernate学习系列-----(3)Session 缓存和持久化生命周期以及Session 基本操作

Session缓存原理 为了能够在控制台更好的看到我们的hibernate干了些什么,可以在hibernate.cfg.xml文件中写入如下配置: <!-- print all generated SQL to the console --> <property name="hibernate.show_sql">true</property> <!-- format SQL in log and console --> <prop

Hibernate事务和并发控制

Hibernate事务和并发控制 ++YONG原创,转载请注明 1.    事务介绍: 1.1.       事务的定义: 事务就是指作为单个逻辑工作单元执行的一组数据操作,这些操作要么必须全部成功,要么必须全部失败,以保证数据的一致性和完整性. 1.2.       事务具有ACID属性: o  原子性(Atomic):事务由一个或多个行为绑在一起组成,好像是一个单独的工作单元.原子性确保在事务中的所有操作要么都发生,要么都不发生. o  一致性(Consistent):一旦一个事务结束了(不

Hibernate事务以及一级缓存02

一. Hibernate中的事务 1. 事务的回顾 1.1 什么是事务(Transaction)(面试重点) 是并发控制的单元,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.通过事务,sql 能将逻辑相关的一组操作绑定在一起,以便服务器 保持数据的完整性.事务通常是以begin transaction开始,以commit或rollback结束.Commint表示提交,即提交事务的所有操作.具体地说就是将事务中所有对数据的更新写回到磁盘上的物理数据库中去,事务正