hibernate实现声明式事务

来源:互联网 发布:淘宝电动洛阳铲 编辑:程序博客网 时间:2024/05/22 17:12

        声明式事务:这里所说的声明,就是指在配置文件中申明。用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可;在不需要事务管理的时候,只要在设定文件上修改一下,即可移去事务管理服务,无需改变代码重新编译,这样维护起来极其方便。

一.AOP式事务声明

1、声明式事务配置
* 配置SessionFactory
* 配置事务管理器
* 事务的传播特性
* 那些类那些方法使用事务

具体配置如下:

<!-- 配置SessionFactory --><bean id="sessionFactory"    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">     <property name="configLocation">           <value>classpath:hibernate.cfg.xml</value>//这个classpath是spring为我们提供的专门用来读取classpath环境下的文件的     </property></bean>
<!-- 配置事务管理器 --><bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">     <property name="sessionFactory">           <ref bean="sessionFactory"/>     </property></bean>
<!-- 那些类那些方法使用事务 --><aop:config>     <aop:pointcut id="allManagerMethod" expression="execution(* com.bjpowernode.usermgr.manager.*.*(..))"/>     <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/>//<aop:advisder>就可以理解为aspect,因为他由pointcut和advice组成的</aop:config>
<!-- 事务的传播特性 --><tx:advice id="txAdvice" transaction-manager="transactionManager">    <tx:attributes>       <tx:method name="add*" propagation="REQUIRED"/>       <tx:method name="del*" propagation="REQUIRED"/>       <tx:method name="modify*" propagation="REQUIRED"/>       <tx:method name="*" propagation="REQUIRED" read-only="true"/>    </tx:attributes></tx:advice>

这样在代码中就不用写管理事务的那些代码了:

public void addUser(User user) throws Exception {//this.getSession().save(user);    this.getHibernateTemplate().save(user);    Log log = new Log();    log.setType("操作日志");    log.setTime(new Date());    log.setDetail("XXX");    logManager.addLog(log);    throw new Exception();}

2、编写业务逻辑方法
* 继承HibernateDaoSupport类,使用HibernateTemplate来持久化,HibernateTemplate是Hibernate Session的轻量级封装
* 默认情况下运行期异常才会回滚(包括继承了RuntimeException子类),普通异常是不会滚的
* 编写业务逻辑方法时,最好将异常一直向上抛出,在表示层(struts)处理
* 关于事务边界的设置,通常设置到业务层,不要添加到Dao上  

 

二.@Transactional实现事务管理

对声明式事务管理,Spring提供基于@Transactional注解方式来实现,但需要Java 5+

注解方式是最简单的事务配置方式,可以直接在Java源代码中声明事务属性,且对于每一个业务类或方法如果需要事务都必须使用此注解。

1、定义业务逻辑实现:

1.package cn.javass.spring.chapter9.service.impl;  2.//省略import  3.public class AnnotationUserServiceImpl implements IUserService {  4.    private IUserDao userDao;  5.    private IAddressService addressService;  6.    public void setUserDao(IUserDao userDao) {  7.        this.userDao = userDao;  8.    }  9.    public void setAddressService(IAddressService addressService) {  10.        this.addressService = addressService;  11.    }  12.    @Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.READ_COMMITTED)  13.    @Override  14.    public void save(final UserModel user) {  15.        userDao.save(user);  16.        user.getAddress().setUserId(user.getId());  17.        addressService.save(user.getAddress());  18.    }  19.    @Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.READ_COMMITTED, readOnly=true)  20.    @Override  21.    public int countAll() {  22.        return userDao.countAll();  23.    }  24.}  

Spring使用@Transaction来指定事务属性,可以在接口、类或方法上指定,如果类和方法上都指定了@Transaction,则方法上的事务属性被优先使用,具体属性如下:

value:指定事务管理器名字,默认使用<tx:annotation-driven/>指定的事务管理器,用于支持多事务管理器环境;

propagation:指定事务传播行为,默认为Required,使用Propagation.REQUIRED指定;

isolation:指定事务隔离级别,默认为“DEFAULT”,使用Isolation.DEFAULT指定;

readOnly:指定事务是否只读,默认false表示事务非只读;

timeout:指定事务超时时间,以秒为单位,默认-1表示事务超时将依赖于底层事务系统;

rollbackFor:指定一组异常类,遇到该类异常将回滚事务;

rollbackForClassname:指定一组异常类名字,其含义与<tx:method>中的rollback-for属性语义完全一样;

noRollbackFor:指定一组异常类,即使遇到该类异常也将提交事务,即不回滚事务;

noRollbackForClassname:指定一组异常类名字,其含义与<tx:method>中的no-rollback-for属性语义完全一样;


2、定义配置文件(applicationContext-service-annotation.xml):

事务相关配置:

<tx:annotation-driven transaction-manager="txManager"/>

使用如上配置已支持声明式事务。

Spring提供的<tx:annotation-driven/>用于开启对注解事务管理的支持,从而能识别Bean类上的@Transactional注解元数据,其具有以下属性:

transaction-manager:指定事务管理器名字,默认为transactionManager,当使用其他名字时需要明确指定;

proxy-target-class:表示将使用的代码机制,默认false表示使用JDK代理,如果为true将使用CGLIB代理

order:定义事务通知顺序,默认Ordered.LOWEST_PRECEDENCE,表示将顺序决定权交给AOP来处理。







0 0
原创粉丝点击