spring@Transactional 사무 가 사용 할 수 없 는 가능 한 원인 에 대해 이야기 합 니 다.

spring transaction
건의 하 다.Spring팀 의 건 의 는 구체 적 인 유형(또는 유형의 방법)에서 사용 @Transactional 주 해 를 하 는 것 이다.
클래스 가 실현 하고 자 하 는 어떠한 인터페이스 에 도 사용 하지 마 세 요.당신 은 당연히 인터페이스 에서@Transactional 주 해 를 사용 할 수 있 습 니 다.
그러나 이 는 인터페이스 기반 프 록 시 를 설정 할 때 만 유효 합 니 다.
주 해 는 계승 할 수 없 기 때문에,
이것 은 만약 에 클래스 기반 에이 전 트 를 사용 하고 있다 면 업무 의 설정 은 클래스 기반 에이 전 트 를 식별 할 수 없다 는 것 을 의미한다.
그리고 대상 도 사무 대리 소 에 포장 되 지 않 는 다.
따라서Spring팀 의 건 의 를 받 아들 이 고 구체 적 인 유형 에서@Transactional 주 해 를 사용 하 십시오.
이 가능 하 다,~할 수 있다,...
spring 의 트 랜 잭 션 설명 가 져 오기
아마

org.springframework.transaction.annotation.Transactional
...이 아니 라

javax.transaction.Transactional
주석 에 대한 해석 이 열 렸 는 지 여부:xml 파일 설정

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
springboot주해 오픈 자동 검색

@EnableTransactionManagement
spring주 해 를 사용 하 는 이 종류의 가방 을 스 캔 할 수 있 습 니까?
설정xml

<context:component-scan base-package="com.xxx.xxx" ></context:component-scan>
springboot 사무 시작

@EnableTransactionManagement
데이터베이스 엔진 은 사 무 를 지원 해 야 합 니 다.
만약mysql이 라면 주의 표 는 사 무 를 지원 하 는 엔진 을 사용 해 야 한다.예 를 들 어InnoDB이 라면myisam사 무 는 소 용이 없다.springboot의 설정

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
검사 방법 이 Public 인지 아 닌 지@Transactional방법 만 이 사무 관 리 를 할 수 있다.
photo_1
이 는public 대 리 를 사용 할 때,Spring AOP 그림 에 있 는Spring 을 호출 하여 목표 방법 집행 전후 로 차단 하기 전에(그림 에서TransactionInterceptor 대리)
Dynamic Advised Interceptor(CglibAopProxy 의 내부 클래스)의 intercept 방법 이나 JdkDynamic AopProxy 의 invoke 방법 은 AbstractFallbackTransactionAttributeSource 를 간접 적 으로 호출 하고 coptute TransactionAttribute 방법 을 호출 합 니 다.

protected TransactionAttribute computeTransactionAttribute(Method method,
    Class<?> targetClass) {
        // Don't allow no-public methods as required.
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
   return null;
  }
 }
이 방법 은cglib아니면 되 돌아 갈 것 이 라 고 판단 할 것 이다public 이상 유형 unchecked 이상
기본적으로null이상 일 때 만 이 사 무 를 다시 시작 합 니 다.unchecked던 진 이상 이 실 행 될 때spring이상 일 때 만 이 사 무 를 스크롤 백 합 니 다.
즉,던 진 이상unchecked의 하위 클래스RuntimeException도 업무 의 스크롤 백 을 초래 할 수 있다.
반면Errors이상 을 던 지면 업무 가 다시 굴 러 가지 않 는 다.이상 을 던 질 때 스크롤 백 을 명확 하 게 설정 할 수 있 습 니 다.
이상 포함checked.이상 하 게 던 질 때 스크롤 백 하지 않 는 것 도 명확 하 게 정의 할 수 있다.checked이상 도 스크롤 백 시 키 려 면 주석 에 이상 유형 을 적 으 면 됩 니 다.

@Transactional (rollbackFor=Exception.class)
checked스크롤 백 하지 않 는 이상 사용자 정의
이상 하 게 캐 치 당 한 거 아니 야?noRollbackFor 층 에서 이상 을 포착 한 후,사무 가 효력 이 발생 하지 않 는 것 을 발견 하 였 다.Service층 에서 손 으로 이상 을 포착 하고 처리 했다Service는 이상 을 먹 은 것 과 같다.try…catch여기 가 잘못 되 었 는 지 모 르 고 자발적으로 데 이 터 를 굴 리 지 않 는 다.추천 방법 은Spring층 에서 이상 을 통일 적 으로 던 지 는 것 이다.
그리고Service층 에서 통일 적 으로 처리 합 니 다.
다음 코드 트 랜 잭 션 은 유효 하지 않 습 니 다.

//   @Transactional   ,  public      
@Service
@Transactional
public class StudentService {

	@Autowired
	private GroupRepository groupRepository;
	@Autowired
	private InstituteRepository instituteRepository;

	public void initStudent() {
		Institute institute = Institute.builder().build();
		institute.setCode("TEST4");
		instituteRepository.save(institute);
		
		//         ,spring        ,        
		try {
			throw new RuntimeException("     ----------        ");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
다음 코드 로 수정

public void initStudent() throws Exception{
  Institute institute = Institute.builder().build();
  institute.setCode("TEST4");
  instituteRepository.save(institute);
  groupRepository.save(group);
  
  //       ,       
  throw new RuntimeException("     ----------        ");
 }
Spring 의 AOP 자동 호출 문 제 를 피하 십시오.
같은 클래스 의 방법 호출(예 를 들 어 a 방법 이 같은 클래스 의 b 방법 을 호출 하 는 것)인지 확인 하여ControllSpring 자체 호출 문 제 를 피한다.AOP Spring 대리 하에 서 목표 방법 만 외부 에서 호출 되 기 때문이다.
목표 방법 은AOP 생 성 된 대리 대상 에 의 해 관리 되 는데 이것 은 자체 호출 문 제 를 초래 할 수 있다.
같은 유형의 다른 주석 이 없 는 방법 은 내부 에서Spring 주석 이 있 는 방법 으로 호출 된다.@Transactional 주석 이 있 는 방법 은 무시 되 고 스크롤 백 이 발생 하지 않 습 니 다.

@Service
public class StudentService {

 @Autowired
 private GroupRepository groupRepository;
 @Autowired
 private InstituteRepository instituteRepository;
 
 //initStudent()   @Transactional(),    
 public void initStudent() throws Exception{
  Institute institute = Institute.builder().build();
  institute.setCode("TEST4");
  instituteRepository.save(institute);
  
  //   initGroup()   @Transactional()           
  initGroup();
  throw new RuntimeException("     ----------        ");
 }
 
 @Transactional()
 public void initGroup() {
  Group group = Group.builder().academic_year(2015).build();
  group.setCode("ELSE1");
  groupRepository.save(group);
 }
}
@Transactional 대체@Transactional 대리
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기