으로 표시된 Service 클래스의 메서드를 보았지만으로 표시 @Transactional
되지 않은 동일한 클래스의 다른 메서드도 호출했습니다 @Transactional
.
별도의 메서드에 대한 호출로 인해 응용 프로그램이 DB에 대한 별도의 연결을 열거 나 부모 트랜잭션을 일시 중단하는 등의 의미가 있습니까?
어노테이션이있는 다른 메소드에 의해 호출되는 어노테이션이없는 메소드의 기본 동작은 무엇입니까 @Transactional
?
답변:
@Transactional
트랜잭션 블록 내에 없는 메서드를 호출 하면 상위 트랜잭션이 새 메서드로 계속됩니다. 부모 메서드 (with @Transactional
)와 동일한 연결을 사용하고 호출 된 메서드에서 발생하는 예외 (without) @Transactional
는 트랜잭션 정의에 구성된대로 트랜잭션을 롤백합니다.
당신이 가진 메서드를 호출하는 경우 @Transactional
와 방법에서 주석을 @Transactional
동일한 인스턴스 내에서 다음 호출 방법 트랜잭션 동작은 트랜잭션에 영향을주지 않습니다. 그러나 트랜잭션 정의가있는 다른 메서드에서 트랜잭션 정의가있는 메서드를 호출하고 다른 인스턴스에있는 경우 호출 된 메서드의 코드는 호출 된 메서드에 제공된 트랜잭션 정의를 따릅니다.
스프링 트랜잭션 문서 의 선언적 트랜잭션 관리 섹션에서 자세한 내용을 확인할 수 있습니다 .
Spring 선언적 트랜잭션 모델은 AOP 프록시를 사용합니다. 따라서 AOP 프록시는 트랜잭션 생성을 담당합니다. AOP 프록시는 인스턴스에있는 메서드가 인스턴스 외부에서 호출되는 경우에만 활성화됩니다.
will follow the transaction definitions given in the called method
. 그러나 호출이 동일한 개체 인스턴스에서 오는 경우에는 호출이 트랜잭션 유지 관리를 담당하는 aop 프록시를 통해 전파되지 않으므로 아무런 영향을 미치지 않습니다.
@Transactional
. 다른 객체 / 인스턴스 의 정의 로 메서드를 호출하면 호출하는 메서드가 다른 @Transactional
속성을 가지고 있더라도 호출 된 메서드는 자체 트랜잭션 정의를 따릅니다.
그것은 전파 수준 에 따라 다릅니다 . 다음은 가능한 모든 레벨 값 입니다.
예를 들어 전파 수준이 NESTED 인 경우 현재 트랜잭션이 "일시 중지"되고 새 트랜잭션이 생성됩니다 ( 참고 : 중첩 트랜잭션의 실제 생성은 특정 트랜잭션 관리자에서만 작동 함 ).
기본 전파 수준 ( "동작"이라고 함)은 REQUIRED 입니다. @Transactional
주석 이있는 (또는 XML을 통해 선언적으로 처리 된) "내부"메서드가 호출 된 경우 동일한 트랜잭션 내에서 실행됩니다. 예를 들어 "새로운 항목 없음"이 생성됩니다.
@Transactional은 트랜잭션 경계 (시작 / 종료)를 표시하지만 트랜잭션 자체는 스레드에 바인딩됩니다. 트랜잭션이 시작되면 원래 메서드가 반환되고 트랜잭션이 커밋 / 롤백 될 때까지 메서드 호출간에 전파됩니다.
@Transactional 어노테이션이있는 다른 메소드가 호출되면 전파는 해당 어노테이션의 전파 속성에 따라 다릅니다.
내부 메서드가 @Transactional로 주석 처리되지 않은 경우 내부 메서드는 외부 메서드에 영향을줍니다.
내부 메서드도 @Transactional with으로 주석 처리 된 경우 REQUIRES_NEW
다음이 발생합니다.
...
@Autowired
private TestDAO testDAO;
@Autowired
private SomeBean someBean;
@Override
@Transactional(propagation=Propagation.REQUIRED)
public void outerMethod(User user) {
testDAO.insertUser(user);
try{
someBean.innerMethod();
} catch(RuntimeException e){
// handle exception
}
}
@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void innerMethod() {
throw new RuntimeException("Rollback this transaction!");
}
내부 메소드에는 주석이 추가되고 REQUIRES_NEW
RuntimeException이 발생하므로 트랜잭션을 롤백하도록 설정하지만 외부 트랜잭션에는 영향을주지 않습니다. 내부 트랜잭션이 시작되면 외부 트랜잭션이 일시 중지되고 내부 트랜잭션이 종료 된 후 다시 시작됩니다. 그들은 서로 독립적으로 실행되므로 외부 트랜잭션이 성공적으로 커밋 될 수 있습니다.