2011-01-16 4 views
2

@TransactionalSpring은 new에 의해 생성 된 객체로 트랜잭션을 시작한다.

public class Pojo { 

    @Transactional 
    public void doInTransaction() { 
     ... 
    } 
} 

annotated 메소드가있는 POJO 클래스 Spring 선언적 트랜잭션 관리는 AOP를 기반으로하지만 그와 관련된 경험은 없습니다. 제 질문은 : (new Pojo).doInTransaction() 만 호출하면 Spring이 트랜잭션을 시작할 수 있습니까?

답변

3

봄 선언적 트랜잭션 관리는 APO에 기반을하지만 난 그 어떤 경험이없는 않습니다.

나는 AOP를 사용하여 트랜잭션 조언을 사용하여 경험을하게 될 것입니다. 좋은 출발점은 here입니다.

는() 만 .doInTransaction을 (새 뽀조)를 호출 할 때, 봄이 트랜잭션을 시작 할 가능성 그것입니다.

아니요, 수동으로 호출 한 Bean을 인식 할 수 없습니다. 그러나 선언적 트랜잭션 관리를 피하고 프로그래밍 방식의 트랜잭션 관리를 원하는 것처럼 들릴 수도 있습니다. Transaction Template을 사용하여 Spring을 사용하는 방법이 있습니다. 그게 니가 찾고 있던거야?

0

스프링이 Annotation을 통해 트랜잭션을 처리하는 방법은 앞서 말했듯이 AOP를 사용하고 있습니다. AOP의 비트는 봄 것, 그것이 작동되도록하기 때문에

그래서 그렇게하기 위해 당신은 스프링 컨테이너를 통해 클래스의 인스턴스를 검색 (여기 뽀조)를해야합니다 (doc 참조) 동적 프록시를 사용하여 구현됩니다 주석 처리 된 메소드를 트랜잭션 관리 코드로 자동 둘러싸는 Pojo를 통해 동적 프록시를 리턴합니다.

은 간단하게 할 경우

Pojo p = new Pojo(); 
p.doInTransaction(); 

봄은 여기에서 재생할 수있는 역할이없는 당신의 메서드 호출은 트랜잭션 내부되지 않습니다.

그래서 당신이해야 할 일이

ApplicationContext springContext = ...; 
Pojo p = (Pojo) springContext.getBean("your.pojo.id"); 
p.doInTransaction(); 

주 같은 것입니다 :이 예를 들어, 당신은 대신 그렇게함으로써 상황에 맞는

에서 수동으로 빈을 검색의 의존성 주입을 선호한다, Spring 컨텍스트를 올바르게 설정하면 Spring은 트랜잭션 주석을 스캔하도록 클래스를 관찰하고 bean을 주석 인식 동적 프록시 인스턴스에 자동으로 래핑해야한다. 아무것도 변경하지 않는 당신의 관점에서, 당신은 여전히 ​​자신의 Classes로 객체를 캐스팅 할 것이지만 Spring context Pojo bean의 클래스 이름을 출력하려고한다면 Proxy $와 같은 것을 얻을 것이다. .. 그리고 당신의 최초의 클래스 이름이 아니라.

어쨌든이 링크를 살펴 유무 : link text

1

다소 성 가긴하지만 성가신 방법으로 AutowireCapableBeanFactory 메커니즘을 사용해야합니다.여기

예를

public interface FooBar{ 
    void fooIze(Object foo); 
} 

public class FooBarImpl implements FooBar{ 
    @Transactional 
    @Override 
    public void fooIze(final Object foo){ 
     // do stuff here 
    } 
} 

같은 트랜잭션 클래스입니다 그리고 여기에 우리가 그것을 사용하는 방법입니다 :

public class FooService implements ApplicationContextAware{ 

    private ApplicationContext applicationContext; 

    @Override 
    public void setApplicationContext(
    final ApplicationContext applicationContext){ 
     this.applicationContext = applicationContext; 
    } 

    public void serviceMethod(){ 

     //declare variable as interface, initialize to implementation 
     FooBar fooBar = new FooBarImpl(); 

     // try to use it, won't work, as it's not a proxy yet 
     Object target = new Object[0]; 
     fooBar.fooIze(target); // no transaction 

     // now let spring create the proxy and re-assign the variable 
     // to the proxy: 
     fooBar = // this is no longer an instance of FooBarImpl!!! 
      (FooBar) applicationContext 
       .getAutowireCapableBeanFactory() 
       .applyBeanPostProcessorsAfterInitialization(fooBar, 
        "someBeanName"); 
     fooBar.fooIze(fooBar); // this time it should work 

    } 

} 

이 가장 좋은 방법이 아닙니다. 한 가지는, 애플리케이션이 스프링 프레임 워크를 잘 인식하게하고, 또한 의존성 주입 원리를 위반한다. 따라서 다른 방법이 없을 때만 이것을 사용하십시오!