2011-03-19 3 views
4

최대 절전 모드 및 지연로드와 관련된 문제가 있습니다.최대 절전 모드 세션 스레딩

배경 : 가 나는 스프링 MVC 웹 응용 프로그램을 가지고, 내 지속성 계층에 대한 최대 절전 모드를 사용합니다. OpenSessionInViewFilter를 사용하여 뷰 레이어의 지연 엔티티를로드 할 수있게했습니다. 그리고 HibernateDaoSupport 클래스를 확장하고 HibernateTemplate을 사용하여 객체를 저장 /로드합니다. 모든 것이 잘 작동하고 있습니다. 지금까지.

문제점

: 나는 웹 요청을 통해 시작할 수 있습니다 작업을해야합니다. 요청이 컨트롤러로 라우팅되면 컨트롤러는이 작업에 대한 새로운 Runnable을 생성하고 스레드를 시작하여 작업을 실행합니다. 그래서 원래의 쓰레드가 리턴 될 것이고 OpenSessionInViewFilter에 의해 ThreadLocal에 놓인 Hibernate 세션은 그 태스크의 새로운 쓰레드에서 사용할 수 없다. 그래서 작업이 일부 데이터베이스 항목을 수행 할 때 나는 악명 높은 LazyInitializationException을 얻습니다.

어느 한 내가 작업에 사용할 수있는 최대 절전 모드 세션을 만들 수있는 가장 좋은 방법을 제안 할 수 있습니까?

읽어 주셔서 감사합니다.

답변

4

Runnable을 봄 콩으로 만들고 @Transactional 주석을 run 이상 추가하십시오. 이 비동기 작업은 웹 요청과 동일한 트랜잭션에서 실행되지 않는다는 경고를 받아야합니다.

그리고 새 스레드를 시작하지 말고 pooling/executor를 사용하십시오.

+1

새로운 스레드를 시작하지 않음으로써 무엇을 의미합니까? – Dejell

+0

@Dejel 아마 [로 스케줄 (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html) 또는 유사한 메커니즘을 활용한다. – user11153

0

올바르게 이해 했습니까? 완전히 전용 된 백그라운드 스레드에서 일부 작업을 수행하겠습니까? 이 경우, Hibernate OpenSessionInViewFilter와 그 세션에 대한 추가 세션 로직에 접근하지 말 것을 권한다. 왜냐하면, 올바르게 언급 되었기 때문에 분리 된 쓰레드에서 실행되고 따라서 원래의 쓰레드에로드 된 정보 (즉, 초기 HttpRequest 처리). 그 스레드 내에서 세션을 열고 닫는 것이 현명한 방법이라고 생각합니다.

그렇지 않으면 왜 분리 된 스레드에서 해당 작업을 실행하는지 질문 할 수 있습니다. 그 동안 작업을 정상적으로 실행하고 사용자에게 '로딩'화면을 표시하는 것으로 충분할 수 있습니까? 여기

1

Runnable 내부의 최대 절전 모드 세션을 사용하는 방법에 대한 작업 예입니다

@Service 
@Transactional 
public class ScheduleService { 

    @Autowired 
    private SessionFactory  sessionFactory; 

    @Autowired 
    private ThreadPoolTaskScheduler  scheduler; 

    public void doSomething() { 

     ScheduledFuture sf = scheduler.schedule(new Runnable() { 
      @Override 
      public void run() { 
       SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(scheduler); 
       final Session session = sessionFactory.openSession(); 
       // Now you can use the session 
      } 
     }, new CronTrigger("25 8 * * * *")); 
    } 
} 

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext()는 빈을 관리하는 Spring에 대한 참조를한다, 그래서 스케줄러 자체는 괜찮습니다. 다른 모든 Spring 관리 Bean도 작동합니다.