首页 > 其他 > 详细

注解@Transactional(rollbackFor = Exception.class) 的用法

时间:2019-04-28 15:23:39      阅读:523      评论:0      收藏:0      [点我收藏+]

由于业务需求要求,在一个Service的一个方法A中有一个for循环,每次循环里面的业务逻辑有可能发生异常,这个时候就需要将这个循环内的所有数据库操作给回滚掉,但是又不能影响到之前循环里数据的更改,并且后面的循环里不发生异常的情况下也需要正常操作数据库

for (int i = 0; i < educationInfoArrayList.size(); i++) {

            String empCode = educationInfoArrayList.get(i).getEmpCode();

            //导入员工信息的工号为自己下属时,则进行插入操作,否则跳过
            EmployeeInfo ei = EmployeeUtils.getCurrentEmployeeInfo();
            String myEmpCode = ei.getEmpNo();
            List<String> subEmployeeList = getSubEmployeeList(myEmpCode);
            if(permission.equals("employee")) {
                if(!subEmployeeList.contains(empCode)) {
                    numOfFailure +=1;
                    uploadFailureInfo = new UploadFailureInfo(empCode, transformEmpCodeToEmpName(empCode), String.valueOf(numOfFailure), EMPLOYEE_IS_NOT_SUBORDINATE);
                    uploadFailureInfoList.add(uploadFailureInfo);
                    log.error("导入员工信息不为自己的下属");
                    continue;
                }
            }

            if(empCode.equals("") || empCode == null){
                numOfFailure +=1;
                uploadFailureInfo = new UploadFailureInfo(empCode, "", String.valueOf(numOfFailure), EMPLOYEE_IS_NULL);
                uploadFailureInfoList.add(uploadFailureInfo);
                log.error("员工工号为空");
                continue;
            }

            String result = insertOrUpdateByOnce(educationInfoArrayList.get(i), beforeEntryArrayList.get(i), afterEntryArrayList.get(i), educationExperienceArrayList.get(i),
                    assessInfoArrayList.get(i), qualificationClassificationArrayList.get(i), trainingInfoArrayList.get(i));
            if(!result.equals("success")){
                numOfFailure +=1;
                uploadFailureInfo = new UploadFailureInfo(empCode, transformEmpCodeToEmpName(empCode), String.valueOf(numOfFailure), result);
                uploadFailureInfoList.add(uploadFailureInfo);
                continue;
            }

        }
@Transactional(rollbackFor = Exception.class)
    public String insertOrUpdateByOnce(EducationInfo educationInfo, BeforeEntry beforeEntry, AfterEntry afterEntry, EducationExperience educationExperience, AssessInfo assessInfo,
            QualificationClassification qualificationClassification, TrainingInfo trainingInfo) {

        try {
            //基本信息
            Map<String, Object> paramMapBase = new HashMap<>();
            paramMapBase.put("empCode", educationInfo.getEmpCode());
            int queryBaseInformationCount = employeeDao.queryBaseInformationCount(paramMapBase);
            //插入或修改时出现错误
            if(queryBaseInformationCount > 0){
                employeeDao.updateBaseInformation(educationInfo);
            }else {
                employeeDao.addEducationInfo(educationInfo);
            }

            //入职神州前履历
            Map<String, Object> paramMapBefore = new HashMap<>();
            paramMapBefore.put("empCode", beforeEntry.getEmpCode());
            paramMapBefore.put("startTime", beforeEntry.getStartTime());
            int queryBeforeEntryCount = employeeDao.queryBeforeEntryCount(paramMapBefore);
            //插入或修改时出现错误
            if(queryBeforeEntryCount > 0){
                employeeDao.updateBeforeEntry(beforeEntry);
            }else {
                employeeDao.addBeforeEntry(beforeEntry);
            }

            //入职神州后履历
            Map<String, Object> paramMapAfter = new HashMap<>();
            paramMapAfter.put("empCode", afterEntry.getEmpCode());
            paramMapAfter.put("startTime", afterEntry.getStartTime());
            int queryAfterEntryCount = employeeDao.queryAfterEntryCount(paramMapAfter);
            //插入或修改时出现错误
            if(queryAfterEntryCount > 0){
                employeeDao.updateAfterEntry(afterEntry);
            }else {
                employeeDao.addAfterEntry(afterEntry);
            }

            //教育经历
            Map<String, Object> paramMapEducation = new HashMap<>();
            paramMapEducation.put("empCode", educationExperience.getEmpCode());
            paramMapEducation.put("startTime", educationExperience.getStartTime());
            int queryEducationExperienceCount = employeeDao.queryEducationExperienceCount(paramMapEducation);
            //插入或修改时出现错误
            if(queryEducationExperienceCount > 0){
                employeeDao.updateEducationExperience(educationExperience);
            }else {
                employeeDao.addEducationExperience(educationExperience);
            }

            //考核评价
            Map<String, Object> paramMapExamine = new HashMap<>();
            paramMapExamine.put("empCode", assessInfo.getEmpCode());
            paramMapExamine.put("time", assessInfo.getTime());
            int queryExamineCount = employeeDao.queryExamineCount(paramMapExamine);
            //插入或修改时出现错误
            if(queryExamineCount > 0){
                employeeDao.updateExamine(assessInfo);
            }else {
                employeeDao.addAssessInfo(assessInfo);
            }

            //资格分类
            Map<String, Object> paramMapQualification = new HashMap<>();
            paramMapQualification.put("empCode", qualificationClassification.getEmpCode());
            paramMapQualification.put("getTime", qualificationClassification.getGetTime());
            int queryQualificationClassificationCount = employeeDao.queryQualificationClassificationCount(paramMapQualification);
            //插入或修改时出现错误
            if(queryQualificationClassificationCount > 0){
                employeeDao.updateQualificationClassification(qualificationClassification);
            }else {
                employeeDao.addQualificationClassification(qualificationClassification);
            }

            //培训情况
            Map<String, Object> paramMapTraining = new HashMap<>();
            paramMapTraining.put("empCode", trainingInfo.getEmpCode());
            paramMapTraining.put("time", trainingInfo.getTime());
            int queryTrainingInfoCount = employeeDao.queryTrainingInfoCount(paramMapTraining);
            //插入或修改时出现错误
            if(queryTrainingInfoCount > 0){
                employeeDao.updateTrainingInfo(trainingInfo);
            }else {
                employeeDao.addTrainingInfo(trainingInfo);
            }
        } catch (Exception e) {
            log.error("插入或者修改异常");
            //失败则手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //返回异常信息
            return e.getCause().getMessage();
        }

        return "success";

    }

catch中加上手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(),事务也没有生效,且报错

org.springframework.transaction.NoTransactionException: No transaction aspect-managed TransactionStatus in scope
    at org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus(TransactionAspectSupport.java:122)
    at com.dubboconsumer.dubboConsumer.service.imp.DemoService.B(DemoService.java:44)
    at com.dubboconsumer.dubboConsumer.service.imp.DemoService.A(DemoService.java:20)
    at com.dubboconsumer.dubboConsumer.service.imp.DemoService$$FastClassBySpringCGLIB$$c7449c96.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
    ...

原因是:调用了同一个类的方法,给这个方法配上事务注解是不会生效的,这个类里面没有事务,不能进行手动回滚;Spring之所以可以对开启@Transactional的方法进行事务管理,是因为Spring为当前类生成了一个代理类,然后在执行相关方法时,会判断这个方法有没有@Transactional注解,如果有的话,则会开启一个事务

    所以,要把执行事务的方法全部丢到一个service类,在这个service类上配上注解@Transactional(rollbackFor = Exception.class),则这个service类中所有的方法都是执行事务的管理

String result = insertOrUpdateEmployeeService.insertOrUpdateByOnce(educationInfoArrayList.get(i), beforeEntryArrayList.get(i), afterEntryArrayList.get(i), educationExperienceArrayList.get(i),
                    assessInfoArrayList.get(i), qualificationClassificationArrayList.get(i), trainingInfoArrayList.get(i));
package com.ucarinc.inner.hrd.transactional;

import com.ucarinc.inner.hrd.dao.EmployeeDao;
import com.ucarinc.inner.hrd.model.employee.AfterEntry;
import com.ucarinc.inner.hrd.model.employee.AssessInfo;
import com.ucarinc.inner.hrd.model.employee.BeforeEntry;
import com.ucarinc.inner.hrd.model.employee.EducationExperience;
import com.ucarinc.inner.hrd.model.employee.EducationInfo;
import com.ucarinc.inner.hrd.model.employee.QualificationClassification;
import com.ucarinc.inner.hrd.model.employee.TrainingInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.HashMap;
import java.util.Map;

/**
 * description:
 *
 * @version 1.0
 */
@Repository
@Transactional(rollbackFor = Exception.class)
public class InsertOrUpdateEmployeeService {

    private static final Logger log = LoggerFactory.getLogger(InsertOrUpdateEmployeeService.class);

    @Autowired
    private EmployeeDao employeeDao;

    public String insertOrUpdateByOnce(EducationInfo educationInfo, BeforeEntry beforeEntry, AfterEntry afterEntry, EducationExperience educationExperience, AssessInfo assessInfo,
                                       QualificationClassification qualificationClassification, TrainingInfo trainingInfo) {

        try {
            //基本信息
            Map<String, Object> paramMapBase = new HashMap<>();
            paramMapBase.put("empCode", educationInfo.getEmpCode());
            int queryBaseInformationCount = employeeDao.queryBaseInformationCount(paramMapBase);
            //插入或修改时出现错误
            if(queryBaseInformationCount > 0){
                employeeDao.updateBaseInformation(educationInfo);
            }else {
                employeeDao.addEducationInfo(educationInfo);
            }

            //入职神州前履历
            Map<String, Object> paramMapBefore = new HashMap<>();
            paramMapBefore.put("empCode", beforeEntry.getEmpCode());
            paramMapBefore.put("startTime", beforeEntry.getStartTime());
            int queryBeforeEntryCount = employeeDao.queryBeforeEntryCount(paramMapBefore);
            //插入或修改时出现错误
            if(queryBeforeEntryCount > 0){
                employeeDao.updateBeforeEntry(beforeEntry);
            }else {
                employeeDao.addBeforeEntry(beforeEntry);
            }

            //入职神州后履历
            Map<String, Object> paramMapAfter = new HashMap<>();
            paramMapAfter.put("empCode", afterEntry.getEmpCode());
            paramMapAfter.put("startTime", afterEntry.getStartTime());
            int queryAfterEntryCount = employeeDao.queryAfterEntryCount(paramMapAfter);
            //插入或修改时出现错误
            if(queryAfterEntryCount > 0){
                employeeDao.updateAfterEntry(afterEntry);
            }else {
                employeeDao.addAfterEntry(afterEntry);
            }

            //教育经历
            Map<String, Object> paramMapEducation = new HashMap<>();
            paramMapEducation.put("empCode", educationExperience.getEmpCode());
            paramMapEducation.put("startTime", educationExperience.getStartTime());
            int queryEducationExperienceCount = employeeDao.queryEducationExperienceCount(paramMapEducation);
            //插入或修改时出现错误
            if(queryEducationExperienceCount > 0){
                employeeDao.updateEducationExperience(educationExperience);
            }else {
                employeeDao.addEducationExperience(educationExperience);
            }

            //考核评价
            Map<String, Object> paramMapExamine = new HashMap<>();
            paramMapExamine.put("empCode", assessInfo.getEmpCode());
            paramMapExamine.put("time", assessInfo.getTime());
            int queryExamineCount = employeeDao.queryExamineCount(paramMapExamine);
            //插入或修改时出现错误
            if(queryExamineCount > 0){
                employeeDao.updateExamine(assessInfo);
            }else {
                employeeDao.addAssessInfo(assessInfo);
            }

            //资格分类
            Map<String, Object> paramMapQualification = new HashMap<>();
            paramMapQualification.put("empCode", qualificationClassification.getEmpCode());
            paramMapQualification.put("getTime", qualificationClassification.getGetTime());
            int queryQualificationClassificationCount = employeeDao.queryQualificationClassificationCount(paramMapQualification);
            //插入或修改时出现错误
            if(queryQualificationClassificationCount > 0){
                employeeDao.updateQualificationClassification(qualificationClassification);
            }else {
                employeeDao.addQualificationClassification(qualificationClassification);
            }

            //培训情况
            Map<String, Object> paramMapTraining = new HashMap<>();
            paramMapTraining.put("empCode", trainingInfo.getEmpCode());
            paramMapTraining.put("time", trainingInfo.getTime());
            int queryTrainingInfoCount = employeeDao.queryTrainingInfoCount(paramMapTraining);
            //插入或修改时出现错误
            if(queryTrainingInfoCount > 0){
                employeeDao.updateTrainingInfo(trainingInfo);
            }else {
                employeeDao.addTrainingInfo(trainingInfo);
            }
        } catch (Exception e) {
            log.error("插入或者修改异常");
            //失败则手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //返回异常信息
            return e.getCause().getMessage();
        }

        return "success";

    }
}

这样就符合事务管理的要求了

注解@Transactional(rollbackFor = Exception.class) 的用法

原文:https://www.cnblogs.com/liuqing576598117/p/10783821.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!