栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring注解@Transactional失效场景分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring注解@Transactional失效场景分析

项目场景: 我在service层进行数据处理的时候,应为考虑到service操作时间过长,不便于在入口处添加@Transactional注解,所以我把service里将进行数据库处理的部分单独拿出来在同类里写了个方法进行事务控制。最初没有在service上直接加上注解就是考虑到,怕过长时间占用数据库,到头来竟然事务直接控制不了了。
问题描述: 事务控制失效 APP 中接收数据代码:
    @Override
    public ResponseStatus addThing(ThingData thingData, String deviceId) {
        ResponseStatus responseStatus = new ResponseStatus(ReturnResponseUtil.getUrl(), thingData.getThingID());

        //实体映射
        ViewThingInfo viewThingInfo = new ViewThingInfo();
        viewThingInfo = (ViewThingInfo) EntryMapping.mapping(viewThingInfo, thingData);
        viewThingInfo.setViewDeviceId(deviceId);
        viewThingInfo.setDeviceId(deviceId);
        viewThingInfo.setCreateTime(new Date());
        //存储处理过图片的子图信息
        List viewThingSubimageInfoList = new ArrayList<>();
        try {
            
            //处理子图信息
            List subImageInfoList = thingData.getSubImageInfoList().getSubImageInfoList();
            for (SubImageInfo subImageInfo : subImageInfoList) {
                ViewThingSubimageInfo viewThingSubimageInfo = new ViewThingSubimageInfo();
                viewThingSubimageInfo = (ViewThingSubimageInfo) EntryMapping.mapping(viewThingSubimageInfo, subImageInfo);
                viewThingSubimageInfoList.add(viewThingSubimageInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            responseStatus.setStatusCode(ErrorResponseCode.INVALID_JSON_CONTENT_CODE);
            responseStatus.setStatusString(ErrorResponseCode.INVALID_JSON_CONTENT_STR);
            return responseStatus;
        }
        
        String msg = null;
        boolean flag = false;
        try {
            flag = thingAdd(viewThingInfo, viewThingSubimageInfoList);
        } catch (Exception e) {
            logger.error("数据处理时发生错误", e);
            msg = e.getMessage();
        }
        if (flag) {//数据处理成功
            responseStatus.setStatusCode(ErrorResponseCode.OK_CODE);
            responseStatus.setStatusString(ErrorResponseCode.OK_STR);
        } else {//数据处理失败
            responseStatus.setStatusCode(ErrorResponseCode.INVALID_JSON_CONTENT_CODE);
            responseStatus.setStatusString("数据处理时发生错误,错误异常[" + msg + "]");
        }
        return responseStatus;

    }
    
@Transactional
    public boolean thingAdd(ViewThingInfo viewThingInfo, List viewThingSubimageInfoList) {
        viewThingInfoMapper.insertViewThingInfo(viewThingInfo);
        for (ViewThingSubimageInfo viewThingSubimageInfo : viewThingSubimageInfoList) {
            viewThingSubimageInfo.setThingId(viewThingInfo.getId());
            viewThingSubimageInfoMapper.insertViewThingSubimageInfo(viewThingSubimageInfo);
        }
        return true;
    }

原因分析: ### 失效场景
  1. 用于非public的方法
  2. 该抛出异常的地方被捕获了,此时没有其它异常的话,不会有回滚
  3. 必须指定 rollbackFor = Exception.class,才可以回滚 checked 和 unchecked 所有异常,否则只会回滚 unchecked 非受检异常
  4. 在同一个类中,一个普通方法调用另外一个有注解(比如@Async,@Transational)的方法,注解是不会生效的

我这里的错误位失效场景4,在同一个类中进行调用


解决方案:

将数据库操纵的放到其它类中进行操作

    @Override
    public ResponseStatus addThing(ThingData thingData, String deviceId) {
        ResponseStatus responseStatus = new ResponseStatus(ReturnResponseUtil.getUrl(), thingData.getThingID());

        //实体映射
        ViewThingInfo viewThingInfo = new ViewThingInfo();
        viewThingInfo = (ViewThingInfo) EntryMapping.mapping(viewThingInfo, thingData);
        viewThingInfo.setViewDeviceId(deviceId);
        viewThingInfo.setDeviceId(deviceId);
        viewThingInfo.setCreateTime(new Date());
        //存储处理过图片的子图信息
        List viewThingSubimageInfoList = new ArrayList<>();
        try {
            
            //处理子图信息
            List subImageInfoList = thingData.getSubImageInfoList().getSubImageInfoList();
            for (SubImageInfo subImageInfo : subImageInfoList) {
                ViewThingSubimageInfo viewThingSubimageInfo = new ViewThingSubimageInfo();
                viewThingSubimageInfo = (ViewThingSubimageInfo) EntryMapping.mapping(viewThingSubimageInfo, subImageInfo);
                viewThingSubimageInfoList.add(viewThingSubimageInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            responseStatus.setStatusCode(ErrorResponseCode.INVALID_JSON_CONTENT_CODE);
            responseStatus.setStatusString(ErrorResponseCode.INVALID_JSON_CONTENT_STR);
            return responseStatus;
        }
        
        String msg = null;
        boolean flag = false;
        try {
            flag = viewThingInfoService.thingAdd(viewThingInfo, viewThingSubimageInfoList);
        } catch (Exception e) {
            logger.error("数据处理时发生错误", e);
            msg = e.getMessage();
        }
        if (flag) {//数据处理成功
            responseStatus.setStatusCode(ErrorResponseCode.OK_CODE);
            responseStatus.setStatusString(ErrorResponseCode.OK_STR);
        } else {//数据处理失败
            responseStatus.setStatusCode(ErrorResponseCode.INVALID_JSON_CONTENT_CODE);
            responseStatus.setStatusString("数据处理时发生错误,错误异常[" + msg + "]");
        }
        return responseStatus;

    }
    @Override
    @Transactional
    public boolean thingAdd(ViewThingInfo viewThingInfo, List viewThingSubimageInfoList) {
        viewThingInfoMapper.insertViewThingInfo(viewThingInfo);
        for (ViewThingSubimageInfo viewThingSubimageInfo : viewThingSubimageInfoList) {
            viewThingSubimageInfo.setThingId(viewThingInfo.getId());
            viewThingSubimageInfoMapper.insertViewThingSubimageInfo(viewThingSubimageInfo);
        }
        return true;
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/318740.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号