2011-08-13 5 views
4

Java 서블릿을 사용하여 작성된 웹 응용 프로그램이 있습니다. Tomcat 7을 서블릿 엔진으로 사용하고 있지만 이전에 Glassfish를 사용했으며 똑같은 문제가있었습니다.Java 웹 응용 프로그램이 느린 MySQL 쿼리에서 멈 춥니 다.

해당 페이지에 5 분마다 업데이트되는 "통계"섹션이 있습니다. 관련된 MySQL 테이블의 크기 때문에 통계 생성에 약 30 초가 걸립니다.

페이지가로드되면 캐시 된 통계를 표시합니다. 페이지의 모든 내용이 렌더링 된 후에는 출력 스트림을 플러시 한 다음 닫습니다. 그런 다음 통계를 업데이트합니다. 이렇게하면 페이지가 완전히로드 된 후 페이지가로드되고 통계가 업데이트되기까지 사용자가 30 초를 기다릴 필요가 없습니다.

문제는 쿼리를 실행하는 동안 페이지를 새로 고치면 쿼리가 완료 될 때까지 페이지가로드되지 않는다는 것입니다. 즉, 초기 사용자에게는 지연이 없음에도 불구하고 긴 지연.

왜 응용 프로그램이 실제로 정지 상태입니까? Tomcat은 하나의 스레드가 여전히 사용 중이더라도 요청을 처리하기 위해 다른 작업자 스레드를 사용할 수 없습니까?

감사합니다.

+1

당신은 문제를 정말 잘 표현했습니다. 그러나 우리는 당신이 질의를 실행하는 방법을 여전히 알고 있어야합니다. 나는이 문제가 모두를 막고있는 동기화 된 방법에 있다고 생각한다. 코드 공유! –

답변

2

데이터가 다시 계산되는 방식에 따라 업데이트가 진행되는 동안 데이터가 "잠겨있을 업데이트"중일 수 있습니다.

이 문제를 해결하는 좋은 방법은 새 계산을 별도의 데이터 영역으로 만든 다음 을 사용하여 이후로 전환하는 것입니다. 이를 구현하는 한 가지 방법은 다음과 같이 데이터베이스보기 및 버전 번호를 사용하고 있습니다 :

create table my_statistics (
    id int not null primary key auto_increment, 
    version int not null, 
    -- other columns with your data 
); 

create table stats_version (current_version int); -- holds just one row 

create view stats as 
select * 
from stats_version v 
join my_statistics s on s.version = v.current_version); 

는 current_version의 버전 번호와 함께 테이블에 새로운 통계를 넣어 + 1. 모든 계산이 이루어진 후. 그런 다음 간단한 update stats_version set current_version = current_version + 1이 새 데이터 사용으로 전환됩니다. 이 마지막 명령문은 실행하는데 단지 수 밀리 초 밖에 걸리지 않으므로 잠금 대기는 아주 작습니다.

전환 후 이전 통계를 삭제하여 공간을 절약 할 수 있습니다.

"스위치"접근 방식을 사용하면 업데이트와 "원자 적 업데이트"가 이루어집니다. 즉, 업데이트가 "즉각적이고 완벽하게"수행되므로 사용자는 부분적으로 변경된 데이터 집합을 볼 수 없습니다.

관련 문제