1. 配置Spring的事务管理
单独对UserService服务来说,在我们目前的实现逻辑里面,其实没有必要专门配置事务管理,但为了统一说明,也为了以后可能事务的需要,我们在这里也解释怎么样将UserService里面的两个方面,配置到Spring的事务管理中去,用Spring里面的事务管理实现,对UserService里面的逻辑进行事务管理.
因为我们使用的是Hibernate进行数据持久化,所有我们接下来配置的,是Spring中基于Hibernate的事务管理,大约要做如下三个方面的配置工作:配置Hibernate事务管理器;配置Spring事务代理类;配置Spring事务代理类所代理的对象,以及对象的要进行事务管理的各个方法. 接下来解释这三个配置的具体操作.
i) 配置Hibernate事务管理器
在applicationContex-service.xml中,添加如下内容,注册一个Hibernat事务管理器 :
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
我们在这里注册了一个基于Hibernate进行事务管理的管理器,它的id名为transactionManager,对应的class中,有利用到Hibernate的SessionFactory,该sessionFactory我们引用前面有已有的定义sessionFactory Bean.引用的sessionFactory Bean在我们配置在往spring框架中添加Hibernate时,有自动将注册内容加入了applicationContext.xml文件,内容如下 :
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>
cn/com/book/demo/hibernate/dao/Tuser.hbm.xml
</value>
<value>
cn/com/book/demo/hibernate/dao/OrderDetail.hbm.xml
</value>
<value>
cn/com/book/demo/hibernate/dao/Shop.hbm.xml
</value>
<value>
cn/com/book/demo/hibernate/dao/Order.hbm.xml
</value>
<value>
cn/com/book/demo/hibernate/dao/Log.hbm.xml
</value></list>
</property>
</bean>
ii) 配置Spring事务代理类
事务管理器我们在上一步配好了,接着就需要配置一个代理,来代理事务管理器,管理我们需要进行事务管理对象的事务管理.在applicationContext-service.xml中加入代理配置的代码如下 :
<bean id="baseServiceProxy" abstract="true" lazy-init="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<!--
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="validate*">PROPAGATION_REQUIRED</prop>
<prop key="do*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
-->
</bean>
在这里我们定一个代理类,id是baseServiceProxy,class是spring框架中的TransactionProxyFactoryBean.它里面需要引用事务管理器实例,我们这里用ref指向上面定义好的事务管理器bean(transactionManager Bean).
在上面的例子中,有一段注释了的property标签,里面定义的是所有要求进行事务管理对象中,需要进行事务管理的公共方法的声明.如果项目中需要进行事务管理的对象中,有很多要进行事务管理的方法的名称一样或差不多,我们就可以在这里进行事务配置,这样就省出了在每个事务对象中都要做重复配置的麻烦.
我们这里没有进行共性方法的配置,所以就隐去了该段的配置
iii) 配置UserService代理对象及要进行事务管理的verifyUser和register方法
在applicationContext-service.xml中加入配置代码如下 :
<bean id="userServiceProxy" parent="baseServiceProxy">
<property name="target">
<ref bean="userService" />
</property>
<property name="transactionAttributes">
<props>
<prop key="register">PROPAGATION_REQUIRED</prop>
<prop key="verifyUser">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
通过上面的脚步,我们就对UserService里面的方法,进行了事务管理的配置.
其中代理的id是userServiceProxy,注意,这名字组成部分是有代理目标的bean的名字,加上Proxy组成.
Bean的parent属性值,是我们在上面一步配置的事务带来bean的id值
事务代理目标,我们是通过target属性中的ref标签进行指定的,这里是userService,是我们在上面有注册的userService bean
至于要进行事务管理的具体方法,我们是通过transactionAttributes属性进行设置的.这里是通过prop标签进行指定,prop的key属性,指定要进行事务管理的方法名称,prop标签包含的值,指定要进行什么样的事务管理.我们这里分别指定了register方法和verifyUser方法,它们的事务管理方式都是PROPAGATION_REQUIRED.其它的方法,是用key值等于*进行指定的,它们的事务管理方式都是PROPAGATION_REQUIRED,readOnly.
Spring中事务管理方法的指定,以及有哪些事务管理方式的详细解释,请查看附录部分