• 侵入代码式 的事务 管理


    在spring aop 事务管理中发现,我们是在service层实现的事务管理。 
    现在有如下场景,大家讨论下看如何实现? 
    ControllerA、ControllerB、ControllerC….共同依赖ServiceA、ServiceB,上述Controller的save操作需要把数据同步ServiceA和ServiceB。 
    由于每个Controller保存ServiceB的extraData字段是通过Json组装的,所以每个Controller具有独特性。如果在Service层实现事务管理,ServiceA将会变的异常庞大,需要判断是哪个Controller过来的数据,然后组装ServiceB的extraData字段。 
    另一种思路,我们是否可以把每个Controller组装ServiceB的extraData字段过程放在各自的Controller,然后在Controller实现事务管理呢? 
    经过测试,在Controller层加事务,在spring.xml的aop:config添加对Controller的声明式事务拦截,结果未生效。在Controller的class加上@Transactional也未生效。最后采取的编程式事务实现的。 
    我们在Spring.xml配置sessionFactory和transactionManager,如果已经配置声明式事务,这步可以忽略。

    <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <property name="dataSource" ref="c3p0DataSource" />
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">#{ nplat['db.dialect'] }</prop>
                    <prop key="hibernate.hbm2ddl.auto">none</prop>
                    <prop key="hibernate.connection.release_mode">after_transaction</prop>
                    <prop key="hibernate.show_sql">false</prop>
                    <prop key="hibernate.format_sql">false</prop>
                    <prop key="hibernate.max_fetch_depth">3</prop><!-- 抓取的级联深度 -->
                    <prop key="hibernate.jdbc.fetch_size">50</prop><!-- 批量抓取的数量.mysql不支持 -->
                    <prop key="hibernate.jdbc.batch_size">30</prop><!-- 批量写入的数量 -->
                    <prop key="javax.persistence.validation.mode">none</prop><!-- HiberV3.5以上需配置该项 -->
                    <!-- <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop 
                        key="hibernate.cache.use_query_cache">false</prop> <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> 
                        强制Hibernate以更人性化的格式将数据存入二级缓存 <prop key="hibernate.cache.use_structured_entries">true</prop> -->
                </props>
            </property>
            <property name="packagesToScan">
                <list>
                    <value>com.gina.gc</value>
                </list>
            </property>
        </bean>
    
        <bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
                <ref bean="sessionFactory" />
            </property>
        </bean>

    然后在每个Controller注入transactionManager:

    @Resource
    private PlatformTransactionManager transactionManager;

    下面讲解如何在Controller的save方法加上编程式事务:

    @RequestMapping("/save")
    @ResponseBody
    public String save(@Validated BaseSetting info) {
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = transactionManager.getTransaction(defaultTransactionDefinition);
    
        try {
            serviceA.save(A);
            serviceB.save(B);
            ...
    
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            e.printStackTrace();
            log.error("sava *** error" + e.toString());
            return ERROR(e.toString());
        }
        return OK();
    }

    这样我们便实现了在Controller层加上事务管理。 
    虽说大家建议把事务加在Service,但不同情况不同处理方案,真正到项目中还得综合考虑,灵活运用。

  • 相关阅读:
    学习:Radio Button和Check Box
    学习:访问Edit Control的七种方法
    实现:EDIT控件字符个数与长度的计算
    学习:GDI基础
    学习:MFC的CWinApp和CFrameWnd
    学习:远程代码注入
    实现:获取指定进程PID
    学习:远程线程实现DLL注入和shellcode注入以及OD调试原理
    学习:内存映射文件
    实现 Trie (前缀树)
  • 原文地址:https://www.cnblogs.com/caozengling/p/9270928.html
Copyright © 2020-2023  润新知