Hibernate 질의가 데이터를 가져 오는 곳 (즉, sedison 캐시 또는 2 차 레벨 캐시 또는 db)을 결정하는 신뢰할 수있는 좋은 방법이 있습니까? 나는 다음과 같은 특성을 가진 최대 절전 모드를 구성하는 경우 : (그들은에서 검색되는 어디 모르겠지만)Hibernate Profiling
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
나는 실행 선택에 대한 정보의 톤을받을 수 있습니다.
private static final class HibernateStatistics implements Serializable {
private static final long serialVersionUID = 1L;
private long queryExecutions = 0;
private long transactions = 0;
private long entityLoads = 0;
private long connects = 0;
private long time = 0;
private double secondLevelHits = 0;
private double secondLevelMisses = 0;
private double queryHits = 0;
private double queryMisses = 0;
public HibernateStatistics(Statistics stats) {
synchronized(stats) {
queryExecutions = -stats.getQueryExecutionCount();
transactions = -stats.getTransactionCount();
entityLoads = -stats.getEntityLoadCount();
connects = -stats.getConnectCount();
secondLevelHits = -stats.getSecondLevelCacheHitCount();
secondLevelMisses = -stats.getSecondLevelCacheMissCount();
queryHits = -stats.getQueryCacheHitCount();
queryMisses = -stats.getQueryCacheMissCount();
time = -System.currentTimeMillis();
}
}
public void update(Statistics stats) {
synchronized(stats) {
queryExecutions += stats.getQueryExecutionCount();
transactions += stats.getTransactionCount();
entityLoads += stats.getEntityLoadCount();
connects += stats.getConnectCount();
secondLevelHits += stats.getSecondLevelCacheHitCount();
secondLevelMisses += stats.getSecondLevelCacheMissCount();
queryHits += stats.getQueryCacheHitCount();
queryMisses += stats.getQueryCacheMissCount();
time += System.currentTimeMillis();
}
}
@Override
public String toString() {
return "Stats"
+ "[ queries=" + queryExecutions
+ ", xactions=" + transactions
+ ", loads=" + entityLoads
+ ", connects=" + connects
+ ", queryCacheHits=" + queryHits
+ ", secondLevelCacheHits=" + secondLevelHits
+ ", time=" + time + " ]";
}
}
:
여기
public class ProfilingInterceptor implements HandlerInterceptor {
@Autowired private SessionFactory sessionFactory;
private static final String STATS = "hibernateStats";
private static final String START_TIME = "startTime";
private static final Logger LOGGER = Logger.getLogger(ProfilingInterceptor.class);
@Override public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
request.getSession().setAttribute(START_TIME, System.currentTimeMillis());
request.getSession().setAttributes(STATS, new HibernateStatistics(sessionFactory.getStatistics());
return true;
}
@Override public boolean postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
HibernateStatistics stats = (HibernateStatistics)
request.getSession().getAttribute("STATS");
stats.update(sessionFactory.getStatistics());
request.getSession().setAttribute(STATS, new HibernateStatistics(sessionFactory.getStatistics()));
LOGGER.debug(stats);
}
@Override public boolean postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
long startTime = (Long) request.getSession().getAttribute(START_TIME);
long currentTime = System.currentTimeMillis();
request.getSession().setAttribute(START_TIME, null);
long totalTime = currentTime - startTime;
LOGGER.debug("URI: " request.getRequestURI() + " Method: "
+ request.getMethod() + " took " + totalTime + "ms.");
HibernateStatistics stats = (HibernateStatistics)
request.getSession().getAttribute(STATS);
stats.update(sessionFactory.getStatistics());
LOGGER.debug(stats);
}
}
(이것은 내부 클래스의)처럼 HibernateStatistics 객체가 모습입니다 : 이것은 스프링 MVC 응용 프로그램입니다, 우리의 모든 요청이 봄 컨트롤러로 처리되어 있기 때문에 나는 다음 인터셉터를 생성
저는 코드에서 N + 1 쿼리 문제가 발생할 수있는 상황을 찾기 위해 단일 스레드 테스트를 활용 해 왔지만이 시점에서 우리의 연결 수와 트랜잭션 수는 모든 페이지에서 잘 나타납니다.
이제는 두 번째 레벨 및 쿼리 캐싱이 얼마나 효과적인지 판단하는 좋은 방법이 필요합니다. 문제는 HibernateStatistics가 쓰레드에 안전하지 않다는 것이다. 그래서 우리가 멀티 쓰레드를 시도 할 때이 값들에 대해 이상한 숫자를 볼 수있었습니다. 통계를 수집하고 추가 분석을 위해 페이지에 표시하는 것만 큼 간단합니까?
내가 넘겨주는 이유는 숫자가 바뀌는 것을 쉽게 볼 수 있기 때문입니다. 요청의 각 단계마다 숫자를 인쇄 할 수는 있지만 수동으로 계산해야합니다. 세션에서 (미리 무효화 된) 세션을 유지하면 자바, 이후 UI에서 얼마나 많은 트랜잭션, 연결 등이 수행되었는지 빠르게 볼 수 있습니다. 로그에있는 선택에 대해 놓친 문서가 있습니까? 일부 쿼리는 캐시되지만 실제로는 인쇄됩니다. – Scott