spring 에서 트 랜 잭 션 주석@Transactional 과 trycatch 사용

spring 트 랜 잭 션 주석@Transactional 과 trycatch
프로젝트 에서@service 층 에서 우 리 는 스프링 의 사무 주 해 를 자주 볼 수 있 습 니 다.@transaction 은 스프링 이 우리 에 게 업무 제 어 를 실현 하도록 도와 주 는 것 을 알 고 있 습 니 다.
하지만 프로젝트 에서 자주 볼 수 있 는 방법 중 에 trycatch 블록 을 포함 하 는 방법 에@transaction 이 주석 되 어 있 습 니 다.
eg:

 @Override
    @Transactional
    public Json addOrder(TOrderAddReq tOrderAddReq) {
  try{
    //     
        } catch (Exception e) {
            .....
            e.printStackTrace();}
//        }
        return json;
    }
상기 방법 을 실행 한 후에 업무 가 실행 되 지 않 은 것 을 볼 수 있 습 니 다.다음 에 예 를 들 어 eg:

 @Override
    @Transactional
    public Json addOrder(TOrderAddReq tOrderAddReq) {
  try{
    //     
        } catch (Exception e) {
         //        spring    
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();}
//        }
        return json;
    }
상기 방법 이 실 행 된 후에 우 리 는 업무 가 마지막 에 실 행 된 것 을 볼 수 있 지만 실제 업무 수행 은 수 동 하 드 코딩 으로 spring 사무 관 리 를 여 는 데 역할 을 했 기 때문에 방법 상의 주 해 는 작용 하지 않 았 다.
다음 예 eg

 @Override
    @Transactional
    public Json addOrder(TOrderAddReq tOrderAddReq) {
  try{
    //     
        } catch (Exception e) {
         
            throw new RuntimeException();
            }
//        }
        return json;
    }
상기 방법 이 실 행 된 후에 우 리 는 업무 가 실 행 된 것 을 볼 수 있 습 니 다.그러나 여기 에는 작은 세부 사항 이 있 습 니 다.@Transactional 은 어떠한 설정 도 하지 않 습 니 다.기본적으로 던 진 unchecked 이상 스크롤 백 입 니 다.checked 이상 은 스크롤 백 되 지 않 습 니 다.모든 이상 이 시 작 될 수 있 도록@Transactional 을@Transactional(rollback For=Exception.class)로 설정 할 수 있 습 니 다.
설명:
spring 의 트 랜 잭 션 경 계 는 업무 방법 을 호출 하기 전에 시 작 됩 니 다.업무 방법 이 실 행 된 후에 commt or rollback 을 실행 합 니 다.(spring 은 기본적으로 runtime 이상 을 던 지 느 냐 에 달 려 있 습 니 다)
runtime exception 을 던 지고 업무 방법 에 catch 가 없 으 면 다시 굴 러 갑 니 다.
일반적으로 업무 방법 에서 catch 이상 이 필요 하지 않 습 니 다.catch 가 필요 하지 않 으 면 하고 싶 은 일 을 한 후에(예 를 들 어 파일 을 닫 는 등)runtime exception 을 던 져 야 합 니 다.그렇지 않 으 면 spring 은 당신 의 조작 commt 를 던 져 서 더러 운 데 이 터 를 만 들 수 있 습 니 다.따라서 catch 코드 는 뱀 을 그 려 서 발 을 더 하 는 것 입 니 다.
@Transactional 스크롤 백 문제(try catch,끼 워 넣 기)
Spring 트 랜 잭 션 주석@Transactional 은 원자 성 을 보장 할 수 있 었 습 니 다.트 랜 잭 션 에 오류 가 있 으 면 전체 트 랜 잭 션 이 스크롤 백 을 보장 할 수 있 지만 try catch 나 트 랜 잭 션 이 포함 되 어 있 으 면 트 랜 잭 션 스크롤 백 에 실패 할 수 있 습 니 다.한 파 를 테스트 하 다.
준비 하 다.
두 장의 표를 만들어 두 개의 데이터 조작 을 모 의 하 다.

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `age` smallint(3) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
테스트
배열 조합 원리 에 따라 우 리 는 네 가지 테스트 를 실시한다.1.try catch 가 없고 끼 워 넣 지 않 는 다.2.try catch 가 있 고 끼 워 넣 지 않 음;3.try catch 가 없고 내장 되 어 있 습 니 다.4.다 있어 요.
가장 간단 한 테스트
만약 우리 가 단순히@Transactional 을 사용한다 면,사 무 는 정상적으로 굴 러 갈 수 있 습 니까?

    @GetMapping("/saveNormal0")
    @Transactional
    public void saveNormal0() throws Exception {
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:"+age);
        userService.save(user);
        throw new RuntimeException();
    }
만약 사무 내 에서 Runtime Exception 오 류 를 보고 했다 면,사 무 는 다시 굴 러 갈 수 있 습 니 다.

    @GetMapping("/saveNormal0")
    @Transactional
    public void saveNormal0() throws Exception {
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:"+age);
        userService.save(user);
        throw new Exception();
    }
트 랜 잭 션 에 Exception 오류(Runtime Exception 오류 가 아 닌)가 발생 하면 트 랜 잭 션 을 되 돌 릴 수 없습니다.

    @GetMapping("/saveNormal0")
    @Transactional( rollbackFor = Exception.class)
    public void saveNormal0() throws Exception {
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:"+age);
        userService.save(user);
        throw new Exception();
    }
Exception 오류(Runtime Exception 이 아 닌)라면 rollback For=Exception.class 인 자 를 더 해도 스크롤 백 이 가능 합 니 다.
결론 1:@Transactional 에 대해 서 는 Runtime Exception 오류 의 스크롤 백 을 보장 할 수 있 습 니 다.Runtime Exception 오류 가 아 닌 스크롤 백 For=Exception.class 인 자 를 추가 해 야 합 니 다.
try catch 영향
블 로 거들 의 다양한 상황 테스트 를 통 해 try catch 는 스크롤 백 자체 에 영향 을 주지 않 고 결론 은 그대로 성립 되 었 다.try catch 는 이상 이@Transactional 에 의 해 감지 되 는 지 여부 에 만 영향 을 줍 니 다.절단면 이 감지 할 수 있 는 정도 로 잘못 던 지면 효과 가 있다.

    @GetMapping("/saveTryCatch")
    @Transactional( rollbackFor = Exception.class)
    public void saveTryCatch() throws Exception{
        try{
            int age = random.nextInt(100);
            User user = new User().setAge(age).setName("name:"+age);
            userService.save(user);
            throw new Exception();
        }catch (Exception e){
            throw e;
        }
    }
예 를 들 어 위의 코드 가 다시 굴 러 간다.

    @GetMapping("/saveTryCatch")
    @Transactional( rollbackFor = Exception.class)
    public void saveTryCatch() throws Exception{
        try{
            int age = random.nextInt(100);
            User user = new User().setAge(age).setName("name:"+age);
            userService.save(user);
            throw new Exception();
        }catch (Exception e){
        }
    }
그러나 catch 의 오 류 를 계속 그물 에 던 지지 않 고 절단면 에서 오 류 를 감지 하지 못 해 처리 할 수 없 으 면 사 무 를 되 돌 릴 수 없습니다.
결론 2:try catch 는 이상 이@Transactional 에 의 해 감지 되 는 지 에 만 영향 을 줍 니 다.절단면 이 감지 할 수 있 는 정도 로 잘못 던 지면 효과 가 있다.
트 랜 잭 션 끼 워 넣 기 영향
먼저 실험 을 통 해 결론 은 여전히 성립 된다.즉,rollback For=Exception.class 를 추가 하지 않 을 때 내외 보 Runtime Exception 을 막론하고 모두 굴 러 간다.런 타임 익 스 셉 션 오류 가 아 닌 내외 신 에 도 굴 러 가지 않 는 다.rollback For=Exception.class 를 더 하면 내외 가 아무리 잘못 보고 해도 굴 러 갑 니 다.이 코드 들 은 제시 하지 않 겠 습 니 다.다음은 다음 두 가지 상황 을 시도 해 보 겠 습 니 다.

    @GetMapping("/out")
    @Transactional( rollbackFor = Exception.class)
    public void out() throws Exception{
        innerService.inner();
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:" + age);
        userService.save(user);
        throw new Exception();
    }
    @Transactional
    public void inner() throws Exception{
        Role role = new Role();
        role.setRoleName("roleName:"+new Random().nextInt(100));
        roleService.save(role);
//        throw new Exception();
    }
상황 1.외부 사무 에 rollback For=Exception.class 를 추가 하지 않 고 내외 에서 각각 오 류 를 보고 하 는 상황 을 테스트 합 니 다(코드 양 을 간소화 하기 위해 외부 에서 오 류 를 보고 하 는 코드 만 제시 합 니 다).모두 스크롤 백 할 수 있 습 니 다.어쨌든 오 류 는 바깥 에 있 는 그 일 에 던 져 졌 고,밖 에 있 는 것 은 rollback For=Exception.class 를 더 해 비 Runtime Exception 오 류 를 처리 하 는 능력 을 갖 추고 있 기 때문에 정상적으로 스크롤 백 할 수 있 습 니 다.
다음은 상황 을 보 겠 습 니 다.2.안의 업무 에 rollback For=Exception.class 를 더 하면 밖 에 더 하지 않 고 밖 에 잘못 보고 합 니 다.

    @GetMapping("/out")
    @Transactional
    public void out() throws Exception{
        innerService.inner();
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:" + age);
        userService.save(user);
        throw new Exception();
    }
    
    @Transactional( rollbackFor = Exception.class)
    public void inner() throws Exception{
        Role role = new Role();
        role.setRoleName("roleName:"+new Random().nextInt(100));
        roleService.save(role);
    }
일 을 되 돌 릴 수 없다 는 것 은 우리 가 의문 을 가지 고 있 는 것 이다.안의 일 은 분명히 매우 강 한 처리 능력 을 가지 고 있 는데 왜 밖 과 함께 되 돌 리 는 데 실 패 했 는 지,조급해 하지 말고,등등 이것 에 대해 이야기 하 자.
그리고 안에 오 류 를 보고 해 보 세 요.

    @GetMapping("/out")
    @Transactional
    public void out() throws Exception{
        innerService.inner();
        int age = random.nextInt(100);
        User user = new User().setAge(age).setName("name:" + age);
        userService.save(user);
    }
     @Transactional( rollbackFor = Exception.class)
    public void inner() throws Exception{
        Role role = new Role();
        role.setRoleName("roleName:"+new Random().nextInt(100));
        roleService.save(role);
        throw new Exception();
    }
어,이번 에는 모두 정상 적 인 스크롤 백 을 진행 했다.오 마 이 갓,이번 에는 밖 에 처리 능력 이 없 는데 왜 안에서 던 진 잘못 을 받 아들 이 고 스크롤 백 을 했 어!!마치 안팎 의 일 들 이 항상 생사 를 같이 하 는 것 처럼 보이 지 않 습 니까?원래@Transactional 에 인자 가 있 습 니 다.원본 코드 를 보 세 요.이 주 해 는 기본 값 도 있 습 니 다.

Propagation propagation() default Propagation.REQUIRED;
REQUIRED 는 사무 가 포 함 될 때 이미 사무 가 존재 하 는 것 을 발견 하면 새 사무 가 아니 라 이 사무 에 가입 하 라 는 뜻 이기 때문에 두 개의 사무 가 존재 하지 않 고 항상 하나 밖 에 없다 는 뜻 이다.이 매개 변수의 다른 값 에 대해 본 고 는 테스트 를 하지 않 는 다.위의 문제 로 돌아 가 외부 에서 잘못 보 고 했 을 때 사 무 를 볼 때 rollback For=Exception.class 인 자 를 추가 하지 않 았 습 니 다.즉,비 Runtime Exception 능력 을 처리 하지 않 았 기 때문에 코드 가 끝 났 습 니 다.'두 개의 사무'인 것 같 습 니 다.모두 스크롤 백 에 실 패 했 습 니 다.안에 잘못 보 고 했 을 때 사 무 는 비 Runtime Exception 처리 능력 을 추 가 했 기 때문에 코드 가 끝나 면 다시 굴 러 가 는 데 성공 했다.
결론 3:REQUIRED 속성 으로 인해'두 개의 사무'는 사실은 하나의 사무 이 고 처리 능력 이 시간 을 잘못 보고 비 Runtime Exception 을 처리 하 는 능력 을 추 가 했 습 니까?
try catch 와 트 랜 잭 션 이 공통 적 으로 영향 을 줍 니 다.
결론 1,2,3 이 성립 된 조건 에서 공 통 된 영향 을 탐색 하 는 문 제 는 훨씬 간단 하 다.상황 이 너무 많 기 때문에 너무 많은 코드 전 시 를 하지 않 는 다.
결론.
결론 1:
@Transactional 에 대해 서 는 Runtime Exception 오류 의 스크롤 백 을 보장 할 수 있 습 니 다.Runtime Exception 오류 가 아 닌 스크롤 백 For=Exception.class 인 자 를 추가 해 야 합 니 다.
결론 2:
try catch 는 이상 이@Transactional 에 의 해 감지 되 는 지 여부 에 만 영향 을 줍 니 다.절단면 이 감지 할 수 있 는 정도 로 잘못 던 지면 효과 가 있다.
결론 3:
REQUIRED 속성 으로 인해'두 개의 사무'는 하나의 사무 이 고 처리 능력 이 잘못된 시간 을 보고 비 Runtime Exception 을 처리 하 는 능력 을 추 가 했 습 니까?
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기