• spring-mvc+mybatis注解方式事务管理


    配置文件:

    <!-- dataSource -->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
            <property name="url" value="${db.master.url}" />
            <property name="username" value="${db.master.user}" />
            <property name="password" value="${db.master.password}" />
            <!-- 配置监控统计拦截的filters -->
            <property name="filters" value="mergeStat,wall,log4j2" />
            <property name="initialSize" value="5" />
            <property name="maxActive" value="100" />
            <property name="minIdle" value="10" />
            <property name="maxWait" value="60000" />
            <property name="validationQuery" value="SELECT 'x'" />
            <property name="testOnBorrow" value="true" />
            <property name="testOnReturn" value="true" />
            <property name="testWhileIdle" value="true" />
            <property name="timeBetweenEvictionRunsMillis" value="60000" />
            <property name="minEvictableIdleTimeMillis" value="300000" />
            <property name="removeAbandoned" value="true" />
            <property name="removeAbandonedTimeout" value="1800" />
            <property name="logAbandoned" value="true" />
        </bean>
    
        <!-- Spring整合Mybatis -->
        <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <!-- 自动扫描Mapping.xml文件 -->
            <property name="mapperLocations" value="classpath*:/sqlMapperXml/*.xml"></property>
            <property name="configLocation" value="classpath:xml/mybatis-config.xml"></property>
            <property name="typeAliasesPackage" value="com.mingwork.model"/>
            <property name="globalConfig" ref="globalConfig"/>
            <property name="plugins">
                <array>
                    <!-- 分页插件配置 -->
                    <bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor">
                        <property name="dialectType" value="mysql"/>
                        <property name="optimizeType" value="aliDruid" />
                    </bean>
                </array>
            </property>
        </bean>
    
        <!-- MP 全局配置 -->
        <bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
            <property name="idType" value="0"/>
            <property name="dbColumnUnderline" value="true"/>
        </bean>
    
        <!-- MyBatis 动态实现  -->
        <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!-- 对Dao 接口动态实现,需要知道接口在哪  -->
            <property name="basePackage" value="com.mingwork.mapper"/>
        </bean>
        <!-- 事务管理 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!-- 事务注解 -->
        <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
        <!-- 事务管理 属性 -->
        <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="select*" propagation="REQUIRED" read-only="true" />
                <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" />
                <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
                <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception" />
                <tx:method name="*" propagation="REQUIRED" />
            </tx:attributes>
        </tx:advice>
    
        <!-- 配置切面 -->
        <aop:config expose-proxy="true" proxy-target-class="true">
            <aop:advisor advice-ref="transactionAdvice" pointcut="execution(* com.mingwork.service..*.*(..))"/>
        </aop:config>
    

      

    上面配置的意思就是配置面向切面,只要servcie中的方法抛出Exception,那么insert,update,delete的sql方法都会回滚。测试时,可以在service方法中故意抛出一个异常,throw new Exception("test"); 那么数据库就不会执行成功。所以在开发时,如果需要对多张表进行操作,而又需要保持事务的一致性的时候,我们就可以把对多张表的操作,写在一个service中的方法中,这样如果有一张表执行失败,抛出异常,其他表的操作也会跟着回滚。

    @Transactional参数说明

    参数说明
    readOnly 是否是只读事务,true表示只读,false表示读写
    timeout 事务超时秒数,默认值-1表示永不超时
    isolation 隔离级别,例如(isolation = Isolation.READ_UNCOMMITTED)
    propagation 事务传播行为,见表propagation说明,例如@Transactional(propagation=Propagation.REQUIRED)
    rollbackFor 需要回滚的异常类数组,例如</br>单一异常类:@Transactional(rollbackFor=RuntimeException.class)</br> 多个异常类:@Transactional(rollbackFor={IndexOutOfBoundsException.class, OutOfMemoryException.class})
    noRollbackFor 不需要进行回滚的异常类数组,......
    rollbackForClassName 需要进行回滚的异常类名称数组,例如</br>单一异常类名称:@Transactional(rollbackForClassName="RuntimeException") </br>多个异常类名称:@Transactional(rollbackForClassName={"IndexOutOfBoundsException","OutOfMemoryException.class"})
    noRollbackForClassName 不需要进行回滚的异常类名称数组,......

    propagation说明

    参数说明
    REQUIRED 有事务,加入事务,没有新建一个
    NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
    REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起
    MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常
    NEVER 以非事务方式执行,如果当前存在事务,则抛出异常
    SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行
    NESTED 如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,则执行与REQUIRED类似的操作

     

     

     

     

     

    Q:我们的工程里,事务的开启跟关闭是由Spring负责的,但具体的SQL语句却是由Mybatis执行的。那么问题来了,Mybatis怎么保证自己执行的SQL语句是处在Spring的事务上下文中?

    仔细思考一下这个过程,@Transactional是由spring进行处理的,spring做的事情是从数据源(一般为数据库连接池,比如说druid,c3p0等)获取一个数据库连接,然后在进入方法逻辑前执行setAutoCommit(false)操作,最后在处理成功或者出现异常的时候分别执行commit或者rollback操作。
    那么问题来了,开启跟结束事务是由spring获取到数据库连接以后进行操作的,但我们实际执行的update或者insert语句却是由mybatis获取数据库连接进行操作的,可以想到如果想让事务生效,那么spring跟mybatis使用的必须是同一个连接,真实情况是什么样呢?它们之间如何进行无缝衔接?让我们通过源码来分析一下。
    具体可以参考下面的链接
    https://www.jianshu.com/p/6a880d20a61f
  • 相关阅读:
    【软件工程实践 · 团队项目】 第一次作业
    课下作业2
    实验三 敏捷开发与XP实践
    2017-2018-1 20155315 《信息安全系统设计基础》第11周学习总结
    2017-2018-1 20155315 《信息安全系统设计基础》实验四 外设驱动程序设计
    20155306 20155315 《信息安全技术》实验四、木马及远程控制技术
    2017-2018-1 20155315 《信息安全系统设计基础》第9周学习总结
    2017-2018-1 20155315 《信息安全系统设计基础》实验三 实时系统
    2017-2018-1 20155315 《信息安全系统设计基础》加分作业:实现mypwd
    2017-2018-1 20155315 《信息安全系统设计基础》第8周学习总结
  • 原文地址:https://www.cnblogs.com/kangjianrong/p/9144977.html
Copyright © 2020-2023  润新知