2013-11-25 3 views
1

내가 무엇을 가지고 :최대 절전 모드 : session.createQuery 및 세션 캐시

나는 내 응용 프로그램의 주 패턴을 통합해야합니다. 즉, 어떤 엔티티의 상태를 변경하면 연쇄 반응이 발생할 수 있습니다. 관련 주체의 상태가 변경 될 수도 있음을 의미하며 관련 주체의 주체보다는 해당 주체 등을 의미합니다.

또한 최대 절전 모드 대화를 사용합니다. 즉, MANUL 플러시 모드를 사용하고 있습니다.

public void handler() { 
    session = beginHibernateConversation(); //open new transaction and new session (if it's needed) 
    entity.changeState(session); //call chain reaction 
    finishhibernateConversation(session); //manual flush, commit, and if it's needed - close session 
} 

어떤 문제 :

나는 모든 변경 사항은 finishhibernateConversation(session) 방법에 DB에 만들어진 수동 플러시 모드를 사용.

session.createQuery 방법은 changeState(session) 방법을 사용해야합니다. 그러나 나는 실제 주체 국가를 볼 수 없다! Beacause 모든 변경 사항은 unflushed 세션에 저장되며 session.createQuery은 세션 컨텍스트와 관련이 없기 때문에 저장됩니다.

질문 :

어떻게 session.createQuerysession cache을 고려하게?

약간의 예 : 예를 들어

내가 Person이 - Job 관계 (one-to-many을). 한 직장의 상태를 full time으로 변경하면 관련 업무를 모두 업데이트해야합니다 (개인이 전일제로만 일할 수 있기 때문에).

그래서, session.createQuery("from Job where person.id = (:id) state in (:states)") [제있어서 내부]

  1. job1.changeState('full time')
  2. (사람 UPDATE 요청 내부)을 수행.

문제는 현재 몇 가지 옵션이 job1

답변

1

이미 변경된 상태에 대해 고려하지 않기 때문에 두 번째 쿼리가 정확하지 않은 것입니다 만,이 문제에 대한 쉬운 변화가 없다 .

1) FlushMode.AUTO을 사용하십시오. 자동 플러쉬 (auto flush)로,이 문제를 피하기 위해 쿼리를하기 전에 Hibernate가 플러시된다. 자동 플러시와 사용중인 패턴간에 충돌이 있으면 안되지만 자동 플러시에는 다른 문제가 있습니다. 일반적으로 매우 동시적인 환경에서는 긴 데이터베이스 트랜잭션을 유지하므로 문제가 발생할 수 있습니다.

2) 이와 같은 쿼리를 만들 때 루트 개체에서 벗어나 메모리에 쿼리하십시오. 이 예제에서, 그것은 사람을 얻는 것과 Job 컬렉션을 통해 반복하는 것과 같습니다.

3) 쿼리 할 항목을 추적하는 ThreadLocal 캐시를 만듭니다. 이것은 모든 옵션 중에서 최악이지만 때로는 필요합니다.

+0

1) 대화 때문에 FlushMode.AUTO를 사용할 수 없습니다. 대화는 사용자가 "CANCEL (취소)"버튼을 누르면 모든 변경 사항을 되돌려 야 함을 의미합니다. 3) 그것은 최악의 경우입니다. 2) 그러나 제발, 저에게 두 번째 대안을 설명해주십시오. –

+1

자동 플러시는 해당 시나리오에서 작동합니다 (데이터베이스로 플러시되지만 데이터베이스 트랜잭션을 커밋하지 않음). 데이터베이스 잠금이 잘못 될 것이므로 권장하지는 않습니다. 두 번째 옵션의 의미는 다음과 같습니다. for (작업 작업 : person.getJobs()) { if (job.getState(). equals (State.SomeValue)) {return job; } } 등. –