接口错误提示:

org.springframework.transaction.UnexpectedRollbackException: 
     Transaction rolled back because it has been marked as rollback-only

根本原因:

在嵌套事务的场景下, 子事务抛出异常. 主事务正常提交. 就导致此原因.

排查:

  1. 检查方法上, 返现都么有使用@Transactional 注解.

  2. 检查配置文件, 发现了Transactional的事务配置.

  3. 根据事务配置,发现命中了主方法和子方法. 导致都开启了事务.

场景:

事务配置:

@Configuration
public class TxCfg {
    @Autowired
    private PlatformTransactionManager transactionManager;

    @Bean(name = "txAdvice")
    public TransactionInterceptor transactionInterceptor() {
        Properties properties = new Properties();
        properties.setProperty("create*", "PROPAGATION_REQUIRED,-Exception,timeout_300"); // 创建类
        properties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception,timeout_300"); // 修改类
        properties.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception,timeout_300"); // 删除类
        properties.setProperty("add*", "PROPAGATION_REQUIRED,-Exception,timeout_300"); // 增加类
        properties.setProperty("minus*", "PROPAGATION_REQUIRED,-Exception,timeout_300"); // 减少类
        properties.setProperty("deal*", "PROPAGATION_REQUIRED,-Exception,timeout_300"); // 处理类
        properties.setProperty("do*", "PROPAGATION_REQUIRED,-Exception,timeout_300"); // 操作类
        TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, properties);
        return txAdvice;
    }

    @Bean
    public BeanNameAutoProxyCreator txProxy() {
        BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
        creator.setInterceptorNames("txAdvice");
        creator.setBeanNames("*Service", "*ServiceImpl");
        creator.setProxyTargetClass(true);
        return creator;
    }
}

主方法:

public RSP updateCustomerInfo(){
    try {
        .....
        ... = fileUploadService.downloadFile();
    catch (Exception e) {
        //吃掉异常
        log.error(e.getMessage(), e);
        rsp = RSP.ok().fail(e.getMessage());
    } finally {
        lock.unlock();
    }
    return rsp;

}

子方法:

内部提示了"文件路径不能为空"

public MultipartFile downloadFile(String ossUrl, String newFileName){
        try {
            Assert.notBlank(ossUrl,"文件路径不能为空");
            Assert.notBlank(newFileName,"文件名称不能为空");
            // 创建OSS实例。
            ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
            conf.setProtocol(Protocol.HTTPS);
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyID, accessKeySecret,conf);
            // 调用oss方法实现下载
            // 第一个参数 Bucket名称
            // 第二个参数 上传到oss文件路径和文件名称
            // 第三个参数 下载
            ossUrl = ossUrl.replace("https://"+bucket+"."+endpoint+"/", "");
            OSSObject ossObject = ossClient.getObject(bucket, ossUrl);
            MultipartFile multipartFile = new MockMultipartFile(newFileName,FileNameUtil.getName(ossObject.getKey()),ossObject.getObjectMetadata().getContentType(),ossObject.getObjectContent());
            // 关闭OSSClient。
            ossClient.shutdown();

            byte[] bytes = compressPicForScale(multipartFile.getBytes(), 800);
            MultipartFile file = new MockMultipartFile(newFileName,FileNameUtil.getName(ossObject.getKey()),ossObject.getObjectMetadata().getContentType(),bytes);
            return file;
        } catch (Exception e) {
            log.error("下载oss文件出错!",e);
            throw new ErrorException("下载oss文件出错!");
        }
    }

文章作者: 刘同学
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 刘同学的小站
后端 Java
喜欢就支持一下吧