Spring 声明式事务无需编写程序代码即实现事务控制:
1.2配置信息参考如下:
1.给每个service 注入时指定spring 代理类:
<bean id="tbljdService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="tbljdServiceTarget"/>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="execute">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="tbljdServiceTarget"
class="com.ssh.service.impl.TblJdServiceImpl">
<property name="tblJdDao">
<ref bean="tblJdDao" />
</property>
<property name="tblQxService">
<ref bean="tblQxService" />
</property>
</bean>
由于以上代码在每个 service 注入的时候指定spring代理类,如果service比较多的话实现比较繁琐,可以把通用的代码统一管理起来,参照以下做法:
<bean id="baseService" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="execute">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="tbljdService" parent="baseService">
<property name="target" ref="tbljdServiceTarget"/>
</bean>
<bean id="tbljdServiceTarget"
class="com.ssh.service.impl.TblJdServiceImpl">
<property name="tblJdDao">
<ref bean="tblJdDao" />
</property>
<property name="tblQxService">
<ref bean="tblQxService" />
</property>
</bean>
事务类型 | 说明 |
PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行(即:不需要事务处理环境,如果有事务正在运行的话,这个方法也可以运行在这个事务里) |
PROPAGATION_MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,表示方法必须运行在自己的事务里。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
可以使用spring2.0 声明式事务简化1.2 。代码如下:
<?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.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="execute" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="serviceMethod"
expression="execution(* com.ssh.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /> </aop:config>
集成SSH框架后,在页面中显示数据时可能导航到另外一个对象,比如页面显示人员信息时需要把人员所在的部门也显示出来,但是部门是在另外一个实体保存的。显示人员对于的部门信息时会出现session 已经关闭的错误。解决办法:在web.xml 中加入过滤器:
<filter>
<filter-name>opensession</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>opensession</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
也可以扩展OpenSessionInViewFilter 参考代码如下:
public class MyOpenSessionView extends OpenSessionInViewFilter {
protected void closeSession(Session session, SessionFactory sessionFactory) {
session.flush();
super.closeSession(session, sessionFactory);
}
protected Session getSession(SessionFactory sessionFactory)
throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.COMMIT);
return session;
}
}
把扩展的类加入到web.xml中替换OpenSessionInViewFilter
事务类型 | 说明 |
PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。(不需要事务处理环境,如果有事务正在运行的话,这个方法也可以运行在这个事务里) |
PROPAGATION_MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。 |