spring事务使用的一点总结

来源:互联网 发布:淘宝采集系统 php源码 编辑:程序博客网 时间:2024/06/05 15:54

spring在处理事务的时候有两种方式:声明式事务和编程式事务,下面就这两种分开来阐述;

1、声明式事务
声明式事务也有两种实现方式:
a、通过TranscationProxyFactoryBean设置spring事务代理,配置方式如下:
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource" />
                <property name="nestedTransactionAllowed" value="true"/>
        </bean>
    <bean id="transactionProxy" class="org.springframework.transaction.interceptor.TranscationProxyFactoryBean">  
                <property name="transactionManager" ref="transactionManager"/>
                <property name="transactionAttributes">
                        <props>
                                <prop key="*">PROPAGATION_NESTED</prop>
                        </props>
                </property>
        </bean>

        业务代码配置需要继承于公用代理类:
        <bean id="***Service" parent="transactionProxy">
                <property name="target">
                        <bean class="*.*.*Service">
                                <property name="*Dao" ref="*Dao"/>
                        </bean>
                </property>
        </bean>
        程序代码中不在需要涉及相关事务代码
    b、通过BeanNameAutoProxyCreator进行自动事务代理,配置方式如下:
        <!-- 事务拦截管理器 -->
        <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TranscationInterceptor">  
                <property name="transactionManager" ref="transactionManager"/>
                <property name="transactionAttributes">
                        <props>
                                <prop key="*">PROPAGATION_NESTED</prop>
                        </props>
                </property>
        </bean>
        <!-- 需要拦截的方法 -->
        <bean id="transcationMethodPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcatAdvisor">
                <property name="mappedNames">
                        <list>
                                <value>*</value><!-- 所有方法 -->
                        </list>
                </property>
                <property name="advice">
                        <ref local="transactionInterceptor"/>
                </property>
        </bean>
        <!-- 需要拦截的类 -->
        <bean id="servicesAutoproxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
                <property name="proxyTargetClass" value="true" />
                <property name="beanNames">
                        <list>
                                <value>*Service</value><!-- 所有方法 -->
                        </list>
                </property>
                <property name="interceptorNames">
                        <list>
                                <value>transcationMethodPointcutAdvisor</value>
                        </list>
                </property>
        </bean>
         程序代码中不在需要涉及相关事务代码
2、编程式事务
编程式事务有两种实现方式:
a、一种是通过注入TransactionTemplate,这种方式需要在配置文件中添加如下代码:
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource" />
                <property name="nestedTransactionAllowed" value="true"/>
        </bean>
        <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">  
                <property name="transactionManager" ref="transactionManager"/>
        </bean>
    dataSource是数据源根据框架要求可以使用JNDI,也可以配置特定数据源
    程序中需要将transactionTemplate注入,例如:
        private TransactionTemplate transactionTemplate;
        public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
                this.transactionTemplate = transactionTemplate;
                //设置事务传播方式
                this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
        }
    程序中调用需要通过回调方式来实现,例如:
       return (Map)this.transactionTemplate.execute(new TransactionCallback(){
                public Object doInTransaction(final TransactionStatus transactionStatus){
                //your self coding
        }
    b、另一中是通过注入PlatformTransactionManager,这种方式需要在配置文件中添加如下代码:
        <beans:bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <beans:property name="dataSource" ref="dataSource" />
                <beans:property name="nestedTransactionAllowed" value="true"/>
        </beans:bean>
     dataSource是数据源根据框架要求可以使用JNDI,也可以配置特定数据源
     程序中需要将transactionManager注入,例如:
        private TransactionStatus transactionStatus;
        private DefaultTransactionDefinition defaultTransactionDefinition;
       
        protected PlatformTransactionManager transactionManager;
        public void setTransactionManager(PlatformTransactionManager transactionManager) {
                this.transactionManager = transactionManager;
                defaultTransactionDefinition=new DefaultTransactionDefinition();
                //设置事务传播方式
                defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
        }
     调用方式比较简单,
        TransactionStatus transactionStatus = transactionManager.getTranscationDefinition(def);
        try{
                //execute code
        }catch(Exception ex){
                transactionManager.rollback(transactionStatus);
                throws ex;
        }
        transactionManager.commit(transactionStatus);