Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 4457|回复: 0

通过手动抛自定义异常实现spring事务回滚

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-16 14:17:36 | 显示全部楼层 |阅读模式

    spring默认事务管理:默认当一个方法出现RunTimeException(运行期异常)时会自动回滚事务。

    有些时候,我们需要从业务上对spring事务进行控制,这时候,如果用spring的默认事务管理,事务没有回滚就达不到我们所期望的结果。

    demo用的spring+mybatis+springmvc+mysql。

    解决方法:

    applicationContext-service.xml 中增删改方法加上rollback-for="MyException",当方法抛出自定义异常被spring接收,会回滚事务。

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" 
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:task="http://www.springframework.org/schema/task"
        xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd 
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-4.2.xsd 
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
            http://www.springframework.org/schema/task
               http://www.springframework.org/schema/task/spring-task-4.2.xsd
            http://code.alibabatech.com/schema/dubbo        
            http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
            
            
            <!-- 配置  扫描   @Service -->
            <context:component-scan base-package="com.educloud.service"/>
            
            <!-- 事务管理器 -->
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <!-- 数据源 -->
            <property name="dataSource" ref="dataSource" />
        </bean>
        <!-- 通知 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 传播行为 -->
                <tx:method name="save*" propagation="REQUIRED" rollback-for="MyException"/>
                <tx:method name="insert*" propagation="REQUIRED" rollback-for="MyException"/>
                <tx:method name="add*" propagation="REQUIRED" rollback-for="MyException"/>
                <tx:method name="create*" propagation="REQUIRED" rollback-for="MyException"/>
                <tx:method name="delete*" propagation="REQUIRED" rollback-for="MyException"/>
                <tx:method name="update*" propagation="REQUIRED" rollback-for="MyException"/>
                <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
                <tx:method name="select*" propagation="SUPPORTS" read-only="true" />
                <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
            </tx:attributes>
        </tx:advice>
        <!-- 切面 -->
        <aop:config>
            <aop:advisor advice-ref="txAdvice"
                pointcut="execution(* com.educloud.service.impl.*.*(..))" />
        </aop:config>
            
            
    </beans>
    View Code

     

    MyException 自定义异常类:

    public class MyException extends Exception {
    
    private String message;
    
    public String getMessage() {
    return message;
    }
    
    public void setMessage(String message) {
    this.message = message;
    }
    
    public MyException(String message) {
    super();
    this.message = message;
    }
    
    public MyException() {
    super();
    }
    
    public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
    }
    
    public MyException(String message, Throwable cause) {
    super(message, cause);
    }
    
    public MyException(Throwable cause) {
    super(cause);
    }
    View Code

     

    ProMapper.java

    package com.educloud.mapper;
    
    import com.educloud.pojo.Pro;
    
    public interface ProMapper {
        
    
        int deletePro(Integer id);
        
        int insertPro(Pro record);
    
        Pro selectPro(Integer id);
    
        int updatePro(Pro record);
    
    }
    View Code

     

    ProMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.educloud.mapper.ProMapper" >
      <resultMap id="BaseResultMap" type="com.educloud.pojo.Pro" >
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="pro_name" property="proName" jdbcType="VARCHAR" />
        <result column="data_flag" property="dataFlag" jdbcType="INTEGER" />
        <result column="create_date" property="createDate" jdbcType="TIMESTAMP" />
      </resultMap>
      
      <sql id="Base_Column_List" >
        id, pro_name, data_flag, create_date
      </sql>
     
      <select id="selectPro" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
        select 
        <include refid="Base_Column_List" />
        from pro
        where id = #{id,jdbcType=INTEGER}
      </select>
      
      <delete id="deletePro" parameterType="java.lang.Integer" >
        delete from pro
        where id = #{id,jdbcType=INTEGER}
      </delete>
      
      
      <insert id="insertPro" parameterType="com.educloud.pojo.Pro" >
          <selectKey keyProperty="id" resultType="Integer" order="AFTER">
              select LAST_INSERT_ID()
          </selectKey>
          
        insert into pro
        <trim prefix="(" suffix=")" suffixOverrides="," >
          <if test="proName != null and proName != '' " >
            pro_name,
          </if>
          <if test="dataFlag != null" >
            data_flag,
          </if>
          <if test="createDate != null" >
            create_date,
          </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides="," >
          <if test="proName != null and proName != '' " >
            #{proName,jdbcType=VARCHAR},
          </if>
          <if test="dataFlag != null" >
            #{dataFlag,jdbcType=INTEGER},
          </if>
          <if test="createDate != null" >
            #{createDate,jdbcType=TIMESTAMP},
          </if>
        </trim>
      </insert>
      
      
      
      <update id="updatePro" parameterType="com.educloud.pojo.Pro" >
        update pro
        <set >
          <if test="proName != null" >
            pro_name = #{proName,jdbcType=VARCHAR},
          </if>
          <if test="dataFlag != null" >
            data_flag = #{dataFlag,jdbcType=INTEGER},
          </if>
          <if test="createDate != null" >
            create_date = #{createDate,jdbcType=TIMESTAMP},
          </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
      </update>
     
    </mapper>
    View Code

     

    ProDetailMapper.java

    package com.educloud.mapper;
    
    import com.educloud.pojo.ProDetail;
    
    public interface ProDetailMapper {
    
        int deleteProDetail(Integer id);
    
    
        int insertProDetail(ProDetail record);
    
    
        ProDetail selectProDetail(Integer id);
    
      
        int updateProDetail(ProDetail record);
    
    }
    View Code

     

    ProDetailMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.educloud.mapper.ProDetailMapper" >
      <resultMap id="BaseResultMap" type="com.educloud.pojo.ProDetail" >
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="pro_detail_name" property="proDetailName" jdbcType="VARCHAR" />
        <result column="data_flag" property="dataFlag" jdbcType="INTEGER" />
        <result column="create_date" property="createDate" jdbcType="TIMESTAMP" />
        <result column="pro_id" property="proId" jdbcType="INTEGER" />
      </resultMap>
      
      <sql id="Base_Column_List" >
        id, pro_detail_name, data_flag, create_date, pro_id
      </sql>
    
      
      <select id="selectProDetail" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
        select 
        <include refid="Base_Column_List" />
        from pro_detail
        where id = #{id,jdbcType=INTEGER}
      </select>
      
      <delete id="deleteProDetail" parameterType="java.lang.Integer" >
        delete from pro_detail
        where id = #{id,jdbcType=INTEGER}
      </delete>
      
      
      <insert id="insertProDetail" parameterType="com.educloud.pojo.ProDetail" >
        insert into pro_detail
        <trim prefix="(" suffix=")" suffixOverrides="," >
          
          <if test="proDetailName != null and proDetailName != '' " >
            pro_detail_name,
          </if>
          <if test="dataFlag != null" >
            data_flag,
          </if>
          <if test="createDate != null" >
            create_date,
          </if>
          <if test="proId != null" >
            pro_id,
          </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides="," >
          
          <if test="proDetailName != null and proDetailName != '' " >
            #{proDetailName,jdbcType=VARCHAR},
          </if>
          <if test="dataFlag != null" >
            #{dataFlag,jdbcType=INTEGER},
          </if>
          <if test="createDate != null" >
            #{createDate,jdbcType=TIMESTAMP},
          </if>
          <if test="proId != null" >
            #{proId,jdbcType=INTEGER},
          </if>
        </trim>
      </insert>
      
      
      
      <update id="updateProDetail" parameterType="com.educloud.pojo.ProDetail" >
        update pro_detail
        <set >
          <if test="proDetailName != null" >
            pro_detail_name = #{proDetailName,jdbcType=VARCHAR},
          </if>
          <if test="dataFlag != null" >
            data_flag = #{dataFlag,jdbcType=INTEGER},
          </if>
          <if test="createDate != null" >
            create_date = #{createDate,jdbcType=TIMESTAMP},
          </if>
          <if test="proId != null" >
            pro_id = #{proId,jdbcType=INTEGER},
          </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
      </update>
      
    </mapper>
    View Code

     

    ProService.java

    package com.educloud.service;
    
    import com.educloud.pojo.Pro;
    import com.educloud.utils.MyException;
    
    public interface ProService {
        
        int deletePro(Integer id) throws MyException;
        
        int insertPro(String proStr) throws MyException;
    
        Pro selectPro(Integer id) throws MyException;
    
        int updatePro(Pro record) throws MyException;
    
    }
    View Code

     

    ProController.java

    package com.educloud.controller;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.educloud.pojo.Pro;
    import com.educloud.service.ProService;
    import com.educloud.utils.MyException;
    
    @Controller
    public class ProController {
        
        @Autowired
        private ProService proService;
        
        @RequestMapping(value="/insertPro")
        @ResponseBody
        public Map<String, Object> insertPro(String proStr){
            //模拟前台数据
            proStr = "{\"pro\": {\"proName\": \"体\"},\"proDetailList\": [{\"proDetailName\": \"身高\"},{\"proDetailName\": \"\"},{\"proDetailName\": \"健康状况\"}]}";
            Map<String, Object> map = new HashMap<>();
            String mString = "";
            try {
                int count = proService.insertPro(proStr);
                mString = "新增成功!";
            } catch (MyException e) {
                mString = e.getMessage();
            }
            map.put("msg", mString);
            return map;
        }
    
    }
    View Code

     

    ProServiceImpl.java

    方法抛出自定义异常  thorw new MyException();

    package com.educloud.service.impl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.educloud.mapper.ProDetailMapper;
    import com.educloud.mapper.ProMapper;
    import com.educloud.pojo.Pro;
    import com.educloud.pojo.ProDetail;
    import com.educloud.service.ProService;
    import com.educloud.utils.MyException;
    
    @Service
    public class ProServiceImpl implements ProService {
        
        @Autowired
        private ProMapper proMapper;
        
        @Autowired
        private ProDetailMapper proDetailMapper;
    
        @Override
        public int insertPro(String proStr) throws MyException{
            // proStr = "{\"pro\": {\"proName\": \"体\"},\"proDetailList\": [{\"proDetailName\": \"身高\"},{\"proDetailName\": \"\"},{\"proDetailName\": \"健康状况\"}]}";
            
            //把json字符串转为json对象
            JSONObject object = JSONObject.parseObject(proStr);
            //获得pro评价指标对象
            JSONObject proObj = object.getJSONObject("pro");
            Pro pro = new Pro();
            pro.setProName(proObj.getString("proName"));
            int count = 0;
            count = proMapper.insertPro(pro);
            if (count ==0) {
                throw new MyException("新增指标失败!");
            }
            //获得proDetail评价指标明细list
            JSONArray proDetailList = object.getJSONArray("proDetailList");
            ProDetail proDetail = null;
            int count1 = 0;
            
            //方式一:
            for (int i = 0; i < proDetailList.size(); i++) {
                //获得proDetail评价指标明细list每一条数据
                JSONObject proDetailObj = proDetailList.getJSONObject(i);
                proDetail = new ProDetail();
                proDetail.setProDetailName(proDetailObj.getString("proDetailName"));
                proDetail.setProId(pro.getId());
                try {
                    count1 += proDetailMapper.insertProDetail(proDetail);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            //抛自定义异常进行事务控制
            if (count1 < proDetailList.size()) {
                throw new MyException("新增指标明细失败!");
            }
            return 1;
            
            //方式二
    //        for (int i = 0; i < proDetailList.size(); i++) {
    //            /**获得proDetail评价指标明细list每一条数据*/
    //            JSONObject proDetailObj = proDetailList.getJSONObject(i);
    //            proDetail = new ProDetail();
    //            proDetail.setProDetailName(proDetailObj.getString("proDetailName"));
    //            proDetail.setProId(pro.getId());
    //            count1 += proDetailMapper.insertProDetail(proDetail);
    //        }
    //        int resultNum = proDetailList.size() + 1; 
    //        /**抛自定义异常进行事务控制*/
    //        if(resultNum == count+count1){
    //            return 1;
    //        }else{
    //            throw new MyException("新增失败!");
    //        }
            
        }
        
        @Override
        public int deletePro(Integer id) throws MyException{
            return proMapper.deletePro(id);
        }
    
        
        @Override
        public Pro selectPro(Integer id) throws MyException{
            return proMapper.selectPro(id);
        }
    
        @Override
        public int updatePro(Pro record) throws MyException{
            return proMapper.updatePro(record);
        }
    
    }
    View Code

     

    Pro.java

    package com.educloud.pojo;
    
    import java.util.Date;
    
    public class Pro {
        private Integer id;
    
        private String proName;
    
        private Integer dataFlag;
    
        private Date createDate;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getProName() {
            return proName;
        }
    
        public void setProName(String proName) {
            this.proName = proName == null ? null : proName.trim();
        }
    
        public Integer getDataFlag() {
            return dataFlag;
        }
    
        public void setDataFlag(Integer dataFlag) {
            this.dataFlag = dataFlag;
        }
    
        public Date getCreateDate() {
            return createDate;
        }
    
        public void setCreateDate(Date createDate) {
            this.createDate = createDate;
        }
    
        @Override
        public String toString() {
            return "Pro [id=" + id + ", proName=" + proName + ", dataFlag=" + dataFlag + ", createDate=" + createDate + "]";
        }
        
        
    }
    View Code

     

    项目百度网盘地址: https://pan.baidu.com/s/1L_zMjmqu-gXRqifcVEfQ1A  提取码: idii 

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-5 15:49 , Processed in 0.066100 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表