서블릿, JavaServer Pages 또는 엔터프라이즈 세션 Bean 마이그레이션 시 연결 고려사항
WebSphere® Application Server 버전 7.0 이상로 업그레이드를 계획하고 J2EE(Java™ 2 Platform, Enterprise Edition) 스펙의 버전 1.2를 1.4 또는 Java EE(Java Platform, Enterprise Edition)와 같은 이상 버전으로 애플리케이션을 마이그레이션 할 계획인 경우, 이후 버전 1.2 애플리케이션 컴포넌트에 다르게 공유 가능 및 공유 불가능한 연결을 할당하는지 인지하십시오. 일부 애플리케이션의 경우, 이 차이로 성능이 저하될 수 있습니다.
불리한 동작 변경
WebSphere Application Server는 J2EE 1.2 스펙에 코딩된 애플리케이션 모듈과의 역호환성을 제공하기 때문에, WebSphere Application Server 버전 7.0 이상로 마이그레이션하면 버전 4 스타일 데이터 소스를 계속 사용할 수 있습니다. J2EE 1.2 모듈용 버전 4 데이터 소스만 구성된 동안 데이터 액세스 애플리케이션 컴포넌트의 동작은 변경되지 않습니다.
WebSphere Application Server 버전 7.0 이상로의 마이그레이션과 함께 J2EE 스펙의 이후 버전을 채택한 경우, 데이터 액세스 컴포넌트의 동작을 변경할 수 있습니다. 특히, 공유 가능한 연결을 통해 로컬 트랜잭션 내 실행되는 엔터프라이즈 세션 Bean, 서블릿 또는 JSP(JavaServer Page) 파일을 포함하는 애플리케이션에 이 위험성이 적용됩니다. 데이터 액세스 컴포넌트의 동작 변경사항은 이러한 애플리케이션의 연결 사용에 불리하게 영향을 줄 수 있습니다.
이 변경사항은 다음 메소드에 포함된 모든 애플리케이션에 영향을 줍니다.
- RequestDispatcher.include()
- RequestDispatcher.forward()
- JSP 포함(<jsp:include>)
문제점의 증상은 다음을 포함합니다.
- 세션 정지
- 세션 제한시간
- 연결 소비
공유 가능 및 공유 불가능한 연결에서의 스위치
버전 4 데이터 소스를 사용하는 J2EE 1.2 모듈의 경우, WebSphere Application Server는 JSP 파일, 서블릿 및 엔터프라이즈 세션 Bean에 대한 공유 불가능한 연결을 실행합니다. 다른 애플리케이션 컴포넌트 모두가 공유 가능한 연결을 실행합니다. 그러나 J2EE 1.3 이상 모듈의 경우, 개별 자원-참조에서 공유 불가능한 것으로 연결을 지정하지 않는 한 애플리케이션 서버는 논리적으로 이름 지정된 자원(개별 참조에 바인드된 자원)에 대한 공유 가능한 연결을 실행합니다. 이 컨텍스트에서 공유 가능 연결을 사용하면 다음 효과가 있습니다.
- 연결 핸들이 close() 호출을 실행하는 경우에도 사용자 트랜잭션의 범위 밖에서 수신되고 사용되는 모든 연결은 자유 연결 풀로 리턴되지 않습니다.
- 사용자 트랜잭션의 범위 밖에서 수신되고 사용되는 모든 연결은 다른 컴포넌트 인스턴스(즉, 기타 서블릿, JSP 파일 또는 엔터프라이즈 Bean)와 공유되지 않습니다. 예를 들어, 세션 Bean 1이 연결된 다음 연결되는 세션 Bean 2를 호출합니다. 모든 특성이 동일하더라도 각 세션 Bean은 자체 소유 연결을 수신합니다.
연결 동작에서 이 변경사항을 기대하지 않는 경우, 애플리케이션 코드를 구성하는 방법이 연결 사용을 초과할 수 있으며, JSP의 경우 특히 공유 가능 연결을 통한 로컬 트랜잭션 내에 실행하는 세션 Bean, RequestDispatcher.include() 루틴, RequestDispatcher.forward() 루틴 또는 이 메소드에서 다른 컴포넌트로의 호출을 포함합니다. 따라서 세션 정지, 세션 제한시간 또는 연결 부족을 경험할 수 있습니다.
예 시나리오
서블릿 A는 연결되며, 작업을 완료하고, 연결을 커미트하고 연결 시 close()를 호출합니다. 다음으로, 서블릿 A는 RequestDispatcher.include()를 호출하여 서블릿 B를 포함하며, 서블릿 A와 같은 단계를 수행합니다. 현재 메소드에서 리턴될 때까지 서블릿 A 연결이 자유 풀로 리턴되지 않기 때문에, 지금 두 연결은 사용 중입니다. 이러한 방법으로, 사용자 애플리케이션에서 계획한 것보다 더 많은 연결을 사용할 수 있습니다. 이 연결이 연결 풀의 Max Connections 설정에서 고려되지 않은 경우, 이 동작으로 풀의 연결이 부족할 수 있으며 ConnectionWaitTimeOut 예외가 발생합니다. connection wait timeout이 사용으로 설정되지 않거나 또는 connection wait timeout이 큰 수로 설정된 경우, 풀에 리턴되지 않는 연결을 대기하기 때문에 이 스레드는 중지된 것으로 나타날 수 있습니다. 새 연결이 사용 불가능한 경우 새 연결을 대기하는 스레드는 현재 사용 중인 스레드를 리턴하지 않습니다.
해결
이러한 문제점을 해결하려면 다음을 수행하십시오.
- 공유되지 않은 연결을 사용합니다.
공유되지 않는 연결을 사용하고 사용자 트랜잭션에 없는 경우, close() 호출을 실행하면(연결을 커미트하거나 롤백하는 것으로 가정) 연결은 자유 풀로 리턴됩니다.
- 연결의 최대 수를 늘리십시오.
필요한 연결 수를 계산하려면, 구성된 스레드의 수를 중첩된 컴포넌트 호출의 가장 깊은 레벨(연결을 사용하는 호출에 대해)로 곱하십시오. 호출 중첩의 설명은 예 시나리오 섹션을 참조하십시오.