这里我们说说spring aop 事务处理的配置,这里有三种方式实现:
这里要注意一点,,要进行事务管理的方法,必须在方法外进行异常的抛出,这样事务管理器才能接收到,然后进行事务的回滚。如果用try-catch处理异常,将不会进行事务回滚。如果必须使用try-catch的话,必须要throw出去。
事务管理器都是使用的声明式事务处理


  • 注解实现
  1. spring.xml配置
<bean
    id="transactionManager"     class="org.springframework.jdbc.datasource.DataSourceTransactionManager"        
    p:dataSource-ref="dataSource" />
<tx:annotation-driven  
    transaction-manager="transactionManager"   
    proxy-target-class="true" />

注意: proxy-target-class=”true” 看自己的需求,是针对类注入还是针对与接口注入,我的项目没有写接口所以加了这个否则这里不用写这个.

  1. 注解方式加事务

探索@Transactional注解:
你可以指定传播、隔离级别、超时以及允许和不允许的异常。
@Transactional注解的属性:

propagation:指定事务定义中使用的传播
isolation:设定事务的隔离级别
timeout:指定事务的超时(秒)
readOnly:指定事务的只读性
noRollbackFor:目标方法可抛出的异常所构成的数组,但通知仍会提交事务
rollbackFor:异常所构成的数组,如果目标方法抛出了这些异常,通知就会回滚事务

  • 涉及到增删改都需要进行事务管理
@Transactional
public Map<String, Object> execCwsDayExec() throws Exception{
    //执行存储过程
    Map<String, Object> params = new HashMap<String, Object>();
    try {
        params.put("iResultCode", 0);
        params.put("iResultName","");
        sqlSession.update(super.DOMAIN_NAME+".execCwsDayExec",params);
    } catch (Exception e) {
        logger.error("执行日终存储过程发生错误:{}", e.getMessage(), e);
        throw e;//非只读事务,如果要try-catch的话,必须throw, 否则事务异常捕捉不到,事务也不会回滚.
    }
    return params;
}
  • 查询不写事务或者只读事务都可以的
@Transactional(readOnly=true)
public CwsDayChange getCurrDayChange() {
    List<CwsDayChange> list=sqlSession.selectList(DOMAIN_NAME
            + ".selectAll");
    if (list.size() > 0)
        return list.get(0);
    else
        return null;
}

  • 使用切面管理事务
  1. spring.xml配置
<bean id="txManager"         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
    <aop:pointcut expression="execution(public * com.ttcity.portal.service..*.*(..))"
        id="bussinessServices" />
    <aop:advisor pointcut-ref="bussinessServices" advice-ref="txAdvice" />
</aop:config>

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="select*" read-only="true" />
        <tx:method name="query*" read-only="true" />
        <tx:method name="find*" read-only="true" />
        <tx:method name="get*" read-only="true" />
        <tx:method name="insert*" propagation="REQUIRED" />
        <tx:method name="add*" propagation="REQUIRED" />
        <tx:method name="save*" propagation="REQUIRED" />
        <tx:method name="modify*" propagation="REQUIRED" />
        <tx:method name="del*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>
  1. 配置说明

切面的关键在于execution(public * com.ttcity.portal.service...(..))的配置,主要说所有返回值的public方法且包名前缀是com.ttcity.portal.service的进行AOP拦截加事务。

而至于事务是只读还是非只读在于
< tx:method name=”select*” read-only=”true” />(只读性) 和< tx:method name=”del*” propagation=”REQUIRED” />(事务性),name的主要作用是函数的前缀,这样就可以拦截切面方法且方法名为select开头的为只读事务,而del开头事务性拦截。


  • 基于SpringAOP的拦截器(主要利用BeanNameAutoProxyCreator自动创建事务代理)
<!--声明式事务管理器 -->
    <bean id="transactionManager"       class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 配置一个事务拦截 -->
    <bean id="trxInterceptor"       class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager" />
        <property name="transactionAttributes">
            <props>             
                <prop key="insert*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,-Throwable</prop>
                <prop key="del*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,-Throwable</prop>
                <prop key="add*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,-Throwable</prop>                
                <prop key="query*">PROPAGATION_SUPPORTS,readOnly</prop>
                <prop key="select*">PROPAGATION_SUPPORTS,readOnly</prop>                
            </props>
        </property>
    </bean>
    <!-- 自动装配事务到bean -->
    <bean id="autoTrx"      class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames">
            <list>
                <value>*BS</value>
            </list>
        </property>
        <property name="interceptorNames">
            <list>
                <value>trxInterceptor</value>               
            </list>
        </property>
    </bean>

我们来说下这个配置,这个配置文件主要要关心
< property name=”transactionAttributes”>节点,下面的props内容主要是增加哪些方法名需要进行什么样的事务处理。例如:

<prop key="insert*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,-Throwable</prop>

是说方法名为insert开头方法进行异常事务处理如果发生异常则需要回滚。

<prop key="query*">PROPAGATION_SUPPORTS,readOnly</prop>

这段代码作用是以query开头方法为只读事务。

到这里我们只知道给哪些方法加事务,但是还不知道哪个类里的方法,这里需要用到BeanNameAutoProxyCreator的相关配置,这个配置会自动装配bean:

<property name="beanNames"> <list> <value>*BS</value> </list> </property>

这段配置作用是拦截以BS结尾的类名,这样我们自动装配bean的配置就写好了。