2011-11-09 3 views
7

같은 클래스에서 다른 @Transactional 메서드를 호출하는 @Transactional 메서드가있는 @Service 클래스가 있습니다. 이것에 대한 롤백 동작을 테스트하고 있었는데 제대로 작동하지 않는 것으로 나타났습니다. "- 롤백 JDBCTransaction를"로그가 표시에도 불구하고, 나는 데이터베이스를 확인하고 변경 사항이 methodOne를 실행 한 후@Transactional 메서드와 롤백을 중첩 한 스프링

@Service 
public class DefaulService implements ervice 
{ 
    @Transactional 
    public void methodOne() 
    { 
     methodTwo(); 

      //question edited 
      //this seems to be the problem 
      this.serviceDAO.executeUpdateOperation(); 

     //test rollback 
     throw new RuntimeException(); 
    } 

    @Transactional 
    public void methodTwo() 
    { 
     //DAO stuff 
    } 
} 

: 코드는 다음과 같이 보입니다.

개별적으로 methodTwo를 호출하고 끝에 예외를 추가하면 변경 사항이 올바르게 롤백됩니다.

중첩 된 @Transactional 호출 중에 발생한 methodOne을 적절히 롤백 할 수있는 방법이 있습니까? 나는 REQUIRED의 기본 전파가 이것을 달성 할 것이라는 인상하에 있었지만 작동하지 않는 것 같습니다. 감사합니다

좋아 UPDATE는, 난 그냥 다른 것을 발견했습니다. 예외가 발생하기 직전에 서비스의 DAO를 호출하고 'executeUpdate'를 통해 수동 업데이트를 수행합니다. 이 행에 주석을 달면 중첩 된 롤백이 작동합니다. 그래서 문제는 실제로 DAO를 호출하고 executeUpdate 쿼리를 실행하는 것 같습니다. 하지만이 또한 현재 트랜잭션 내에서 실행하면 안됩니까?

+0

당신은'methodOw()'에서'methodTwo()'를 호출 할 때'@ Transactional' 주석이 무시된다는 것을 알고 있습니까? 자세한 내용은 내 [기사] (http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html)를 참조하십시오. 그러나 이것은 당신의 문제를 일으키는 것은 아니지만 알아 두어야 할 가치가 있습니다. –

+0

예, 그렇지만 MethodTwo를 독립적으로 호출 할 수 있으므로 이러한 경우에는 고유 한 주석이 필요합니다. 지금은 기본 동작이지만 executeUpdate가 트랜잭션을 커밋하게 만드는 이유에 관해서는 당황 스럽다. – JayPea

+1

serviceDao의 트랜잭션 전파는 무엇입니까? 어쨌든 REQUIRES_NEW입니까? – Hendrik

답변

1

메소드를 호출 할 때 bean factory에서 "ervice"의 인스턴스를 얻는 것은 분명합니다. 빈 팩토리는 각 메소드 호출을 중심으로 트랜잭션 로직을 구현하는 프록시를 설정해야한다. 나는이 방식이 "외부인"이 프록시를 통해 메소드를 호출 할 때만 효과가 있었고 한 메소드가 다른 메소드를 호출 할 때 작동하지 않는다는 인상을 받았다. 그 메소드는 구현 객체 내에서 직접 호출이며 AOP 프록시를 거치지 않기 때문이다.

+0

이것은 사용하는 AOP 접근법의 종류에 따라 다릅니다. Tomasz Nurkiewicz의 [link] (http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html)를 확인하십시오. 또한 JayPea가 설명하는 동작을 설명 할 수 없습니다. –