作者微信 bishe2022

代码功能演示视频在页面下方,请先观看;如需定制开发,联系页面右侧客服
Hibernate编程式事务与Spring Aop的声明式事务(spring与hibernate集成)

Custom Tab

Java代码  收藏代码

采用编程式事务  
  
事务主要分为:编程式事务和声明式事务  
  
1、SessionFactory.getCurrentSession()和SessionFactory.openSession()的区别?  
    * 如果是SessionFactory.getCurrentSession()来创建session,在commit后session就  
      自动关闭了,也就是不用再session.close()了  
    * 如果使用的是SessionFactory.openSession()必须显示的关闭session,因为commit后不会关闭  
      
    参见:HIBERNATE_HOME/doc/tutorial下的项目  
      
2、SessionFactory.getCurrentSession()的配置,需要在hibernate.cfg.xml文件中加入,如下配置:  
    *本地事务jdbc事务  
        <property name="hibernate.current_session_context_class">thread</property>  
    *全局事务jta事务  
        <property name="hibernate.current_session_context_class">jta</property>

 关于Hibernate的编程式事务,我们以增加用户的同时向数据库插入日志为例说明。

主要代码如下:

Java代码  收藏代码

package com.bjsxt.usermgr;  
  
import com.bjsxt.usermgr.manager.UserManager;  
import com.bjsxt.usermgr.manager.UserManagerImpl;  
import com.bjsxt.usermgr.model.User;  
  
  
public class UserMangerTest {  
      
    public static void  main(String[] args) {  
        User user = new User();  
        user.setName("张三");  
          
        UserManager userManager = new UserManagerImpl();  
          
        userManager.addUser(user);  
    }  
}

Java代码  收藏代码

package com.bjsxt.usermgr.manager;  
  
import java.util.Date;  
  
import org.hibernate.Session;  
  
import com.bjsxt.usermgr.model.Log;  
import com.bjsxt.usermgr.model.User;  
import com.bjsxt.usermgr.util.HibernateUtils;  
  
public class UserManagerImpl implements UserManager {  
  
    public void addUser(User user) {  
        Session session = null;  
        try {  
            //session = HibernateUtils.getSession();  
            session = HibernateUtils.getSessionFactory().getCurrentSession();  
            session.beginTransaction();  
              
            //持久化user  
            session.save(user);  
              
            Log log = new Log();  
            //log.setType("安全日志");  
            log.setType(null);  
            log.setDetail("xxx用户尝试登录。。。");  
            log.setTime(new Date());  
            LogManager logManager = new LogManagerImpl();  
              
            logManager.addLog(log);  
              
            session.getTransaction().commit();  
        }catch(Exception e) {  
            e.printStackTrace();  
            session.getTransaction().rollback();  
        }  
    }  
}

Java代码  收藏代码

package com.bjsxt.usermgr.manager;  
  
import org.hibernate.Session;  
  
import com.bjsxt.usermgr.model.Log;  
import com.bjsxt.usermgr.util.HibernateUtils;  
  
public class LogManagerImpl implements LogManager {  
  
    public void addLog(Log log) {  
        Session session = HibernateUtils.getSessionFactory().getCurrentSession();  
        session.save(log);  
    }  
  
}

注意上面我们使用了getCurrentSession,所以没用显式调用closeSession方法关闭session.

当增加用户的时候将插入一条数据到user表,而同时加入一条日志到log表。

那么当log.setType(null);时因为type字段不能为空,所以按编程式事务将不会在user,log表中的任何一个插入数据。即发生回滚。

具体代码见spring_hibernate_1项目。

 

下面我们使用spring的声明式事务来对上面代码进行改进。

显然我们将要集成spring与hibernate.

配置方法:

Java代码  收藏代码

集成spring和hibernate  
    * 把hibernate和spring的包引入  
    * 声明式事务的配置  
     --配置SessionFactory  
     --配置事务管理器  
     --配置事务的传播特性  
     --配置哪些类的哪些方法进行事务管理   
     * 继承HibernateDaoSupport类,使用HibernateTemplate这个类来持久化数据,HibernateTemplate类  
        实际上是session的封装  
     * 默认回滚异常是RuntimException,即运行时异常,普通异常不回滚  
     * 在编写异常时最好一直向上抛出,有呈现层处理  
     * spring的事务管理需要添加在业务逻辑方法上,不要添加到DAO上

按照上面方法我们对spring_hibernate_1项目进行改进。

首先我们引入spring所需类库:我的自定义spring库里有:spring.jar,log4j-1.2.15.jar, common-logging.jar, aspectjrt.jar, aspectjweaver.jar, cglib-nodep-2.1.3.jar

第二步进行声明式事务的配置:

我们新建一个spring的配置文件applicationContext-common.xml

内容如下:

Java代码  收藏代码

<?xml version="1.0" encoding="UTF-8"?>  
  
<beans xmlns="http://www.springframework.org/schema/beans"  
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
        xmlns:aop="http://www.springframework.org/schema/aop"  
        xmlns:tx="http://www.springframework.org/schema/tx"  
        xsi:schemaLocation="  
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"  
          
>  
    <!-- 配置sessionFactory -->  
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="configLocation">  
            <value>classpath:hibernate.cfg.xml</value>  
        </property>  
    </bean>  
      
    <!-- 配置事务管理器 -->  
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory"></property>  
    </bean>  
      
    <!-- 配置事务传播特性 -->  
    <tx:advice id="txAdvice" transaction-manager="transactionManager">  
        <tx:attributes>  
            <tx:method name="add*" propagation="REQUIRED"/>  
            <tx:method name="*" read-only="true"/>  
        </tx:attributes>  
    </tx:advice>  
      
    <!-- 配置哪些类的方法进行事务管理 -->  
    <aop:config>  
        <aop:pointcut expression="execution(* com.bjsxt.usermgr.manager.*.*(..))" id="addManagerMethod"/>  
        <aop:advisor advice-ref="txAdvice" pointcut-ref="addManagerMethod"/>  
    </aop:config>  
</beans>

第三步,我们把Dao层UserManagerImpl,LogManagerImpl继承HibernateDaoSupport,并利用getHibernateTemplate方法来获得session,对UserManagerImpl增加属性logManager,并通过ioc设置属性。

Java代码  收藏代码

package com.bjsxt.usermgr.manager;  
  
import java.util.Date;  
  
import org.hibernate.Session;  
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;  
  
import com.bjsxt.usermgr.model.Log;  
import com.bjsxt.usermgr.model.User;  
import com.bjsxt.usermgr.util.HibernateUtils;  
  
public class UserManagerImpl extends HibernateDaoSupport implements UserManager {  
  
    private LogManager logManager;  
      
    public void addUser(User user) {  
        this.getHibernateTemplate().save(user);  
            Log log = new Log();  
//          log.setType("安全日志");  
            log.setType(null);  
            log.setDetail("xxx用户尝试登录。。。");  
            log.setTime(new Date());  
              
            logManager.addLog(log);  
    }  
      
    public void setLogManager(LogManager logManager) {  
        this.logManager = logManager;  
    }  
}

Java代码  收藏代码

package com.bjsxt.usermgr.manager;  
  
import org.hibernate.Session;  
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;  
  
import com.bjsxt.usermgr.model.Log;  
import com.bjsxt.usermgr.util.HibernateUtils;  
  
public class LogManagerImpl  extends HibernateDaoSupport implements LogManager {  
  
    public void addLog(Log log) {  
        this.getHibernateTemplate().save(log);  
    }  
  
}

第四步:创建另一个配置文件applicationContext-beans.xml

Java代码  收藏代码

<?xml version="1.0" encoding="UTF-8"?>  
  
<beans xmlns="http://www.springframework.org/schema/beans"  
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
        xmlns:aop="http://www.springframework.org/schema/aop"  
        xmlns:tx="http://www.springframework.org/schema/tx"  
        xsi:schemaLocation="  
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"  
          
>  
    <bean id="logManager" class="com.bjsxt.usermgr.manager.LogManagerImpl">  
        <property name="sessionFactory" ref="sessionFactory"></property>  
    </bean>  
    <bean id="userManager" class="com.bjsxt.usermgr.manager.UserManagerImpl">  
        <property name="logManager" ref="logManager"></property>  
        <property name="sessionFactory" ref="sessionFactory"></property>  
    </bean>

测试类:

Java代码  收藏代码

  1. package com.bjsxt.usermgr;  
      
    import org.springframework.context.ApplicationContext;  
    import org.springframework.context.support.ClassPathXmlApplicationContext;  
      
    import com.bjsxt.usermgr.manager.UserManager;  
    import com.bjsxt.usermgr.model.User;  
      
      
    public class UserMangerTest {  
          
        public static void  main(String[] args) {  
            User user = new User();  
            user.setName("张三");  
              
            ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext-*.xml");  
            UserManager userManager = (UserManager)act.getBean("userManager");  
            userManager.addUser(user);  
        }
  2. 测试插入成功,然后将log.setType("安全日志");改为 log.setType(null);,看是否有事务回滚。

  3. 具体代码见spring_hibernate_3.rar


转载自:http://quicker.iteye.com/blog/674029

Home