제2장 아웃바운드 관리

내용 목차

2.1. Connection Pool과 Connection 관리
2.1.1. 애플리케이션의 Connection 요청 패턴
2.1.2. 리소스 어댑터와 Connection Pool의 관계
2.1.3. Connection Pool의 장점
2.1.4. Connection Pool 설정
2.1.5. Connection Pool 기능
2.2. 트랜잭션 관리
2.2.1. 로컬 트랜잭션 리소스의 글로벌 트랜잭션(XA) 참여 기능
2.2.2. 글로벌 트랜잭션(XA)과 Connection Sharing
2.3. Connection Pool 설정 예제
2.3.1. Connection Factory가 1개인 경우
2.3.2. Connection Factory가 2개 이상인 경우
2.4. Connection Pool 모니터링 및 제어
2.4.1. Connection Pool 제어
2.4.2. Connection Pool 모니터링

본 장에서는 애플리케이션에서 EIS로 향하는 아웃바운드(Outbound) 커뮤니케이션에서 JEUS의 역할과 기능들을 Connection Pool과 트랜잭션 연동을 중심으로 설명한다.

아웃바운드 커뮤니케이션에서 애플리케이션이 EIS로 요청을 하고 그에 대한 결과를 받는 경우 Connection이 필요하다. JEUS에서는 애플리케이션이 Connection을 효율적으로 사용할 수 있도록 Connection Pool을 제공한다.

애플리케이션은 Connection Factory를 요청한 다음, 해당 Factory에서 Connection을 얻을 수 있다. 이는 JDBC Connection을 얻을 때 데이터소스를 lookup하고 데이터소스로부터 Connection을 얻는 방식과 같다.

다음은 애플리케이션의 Connection 요청 패턴에 대한 예제이다.

// obtain the initial JNDI Naming context
Context initctx = new InitialContext();
// perform JNDI lookup to obtain the connection factory
javax.resource.cci.ConnectionFactory connectionFactory = 
  (javax.resource.cci.ConnectionFactory)initctx.lookup(“java:comp/env/eis/sampleEIS”);
javax.resource.cci.Connection conn = connectionFactory.getConnection();
try {
   // do some works
} finally {
   conn.close();
}

참고

예제에서는 CCI를 예로 들었지만 실제로 Connection Factory는 특별히 정의된 인터페이스가 있는 것이 아니라 리소스 어댑터에서 독자적으로 정의하고 이를 애플리케이션이 사용할 수 있다.

만약 위의 애플리케이션이 EJB라고 한다면 Annotation 또는 ejb-jar.xml의 <resource-ref>를 다음과 같이 설정해야 한다.


이때 jeus-ejb-dd.xml에는 'eis/sampleEIS'가 실제 매핑될 JNDI 이름을 설정해야 한다.

다음 예제의 'sampleConnectionPool'은 리소스 어댑터를 deploy할 때 jeus-connector-dd.xml에 기술해주는 Connection Pool의 JNDI 이름이다.


애플리케이션이 JNDI를 통해서 Connection Factory를 요청하면, JEUS는 리소스 어댑터로 Connection Factory 생성을 요청한다.

JEUS가 Connection Factory의 생성을 요청할 때는 리소스 어댑터로 Connection Manager를 전달한다. 이 Connection Manager의 구현체가 바로 JEUS Connection Pool이다.

리소스 어댑터가 Connection Factory를 생성해서 JEUS로 넘겨주면 이를 애플리케이션에 전달한다. 애플리케이션이 전달받은 Connection Factory에 Connection을 요청하면 리소스 어댑터는 JEUS가 넘겨준 Connection Manager에 Connection을 요청한다. 이렇게 되면 JEUS Connection Manager는 Pooling하고 있던 물리적 Connection(또는 ManagedConnection)을 하나 꺼내서 Connection Handle을 생성한 다음 이를 리소스 어댑터로 리턴한다. 그러면 리소스 어댑터가 이를 애플리케이션으로 전달한다. 물리적 Connection과 Connection Handle은 JCA 표준에 정의되어 있는 개념이다.

애플리케이션은 Connection이 더 이상 필요없을 때는 반드시 반납해야 한다. 이를 일반적으로 "Connection을 닫는다"라고 표현한다. 만약 애플리케이션이 제대로 Connection을 닫지 않을 때는 항상 Connection Leak 현상이 발생하게 된다.

JEUS가 넘겨준 Connection Manager를 사용하는 것은 리소스 어댑터의 선택이다. 만약 리소스 어댑터가 Connection Manager를 사용하지 않고 내부적으로 Connection을 생성한다면 JEUS는 Connection 관리 및 애플리케이션과 EIS 간의 커뮤니케이션 과정에 관여하지 않는다.

참고

1. Connection Manager에 관한 자세한 내용은 javax.resource.spi.ConnectionManager 및 javax.resource.spi.ManagedConnectionFactory의 Javadoc 및 JCA 표준을 참고한다.

2. 물리적 Connection과 Connection Handle의 자세한 내용은 JCA 표준의 "Chapter 6. Connection Management"를 참고한다.

JCA Connection Pool은 리소스 어댑터를 deploy할 때 jeus-connector-dd.xml을 기술해서 설정한다.

이때 애플리케이션에서 Connection Pool을 사용하기 위해서는 JNDI 이름이 꼭 필요하기 때문에 JEUS에서 정한 규칙에 따라 자동으로 생성한다. 그러나 사용자가 직접 JNDI 이름을 지정하는 경우에는 jeus-connector-dd.xml에 반드시 기술해야 한다. jeus-connector-dd.xml의 <jeus-connector-dd> 하위의 <connection-pool>을 사용하여 설정한다. jeus-connector-dd.xml를 RAR에 포함시키는 방법은 “제4장 리소스 어댑터”를 참고한다.

JCA 표준에 의해 하나의 리소스 어댑터에는 여러 개의 Connection Pool을 설정할 수 있다. 이러한 Connection Pool의 기준이 되는 것은 ra.xml의 <connection-definition>과 그 하위 요소인 <connectionfactory-interface>이다. 만약 <connection-definition>이 5개 설정되어 있다면 JEUS에는 최소 5개의 Connection Pool이 구성된다.

주의

ra.xml에 정의하는<connectionfactory-interface>는 중복될 수 없다. 중복되는 값이 있을 경우에는 ra.xml의 유효성 검사가 실패하게 되어 deploy되지 않는다.

다음은 jeus-connector-dd.xml의 각 태그에 대한 설명이다. 실제 설정에 대한 예는 “2.3. Connection Pool 설정 예제”를 참고한다.

참고

Connection Match, Lazy Transaction Enlistment와 관련된 자세한 내용은 JCA 표준을 참고한다.

Connection Pool은 Connection의 유효성을 검사할 수 있고 Connection Leak에 대해 처리할 수 있는 기능을 갖는다.

Connection 유효성 검사

애플리케이션이 Connection 요청을 했을 때 리소스 어댑터로 Connection의 유효성(Connection Validation)에 대해 검사를 요청하는 기능이다. 이 기능은 Connection의 내부적인 에러로 인한 끊김, 방화벽에 의한 소켓 끊김 현상 등을 체크할 때 유용하다. 검사이 실패하면 물리적 Connection을 새로 생성하여 그에 대한 핸들을 애플리케이션으로 리턴한다.

만약 유효성 검사 작업이 너무 잦아서 오버헤드가 발생한다면 <non-validation-interval>에 대해 설정한다. 이는 Connection 검사를 수행할 때의 시각과 맨 마지막에 Connection을 사용한 시각과의 차이가 이미 설정한 interval 내에 있다면 무조건 유효하다고 판단하고 검사를 하지 않도록 하는 설정이다.

예를 들어 interval을 5초(5000ms)라고 설정했을 때, Connection을 마지막에 사용한 후 아직 5초가 지나지 않았다면 그 Connection이 무조건 유효하다고 가정하는 것이다.

다음은 <non-validation-interval>의 설정 예이다.

<non-validation-interval>5000</non-validation-interval>

주의

리소스 어댑터에서 반드시 javax.resource.spi.ValidatingManagedConnectionFactory를 구현해야만 Connection의 유효성을 검사할 수 있다. 리소스 어댑터로 검사을 요청했을 때 외부 리소스 측에서 응답이 오지 않아서 계속 기다리게 되는 상황이 발생할 수 있다. 현재 WAS에서는 이러한 문제를 해결할 수 있는 방법이 없으므로 리소스 어댑터 측에서 타임아웃 옵션을 제공할 필요가 있다.

사용자는 유효성 검사에 실패한 경우 해당 Connection Pool에 있는 나머지 Connection들에 대해 Destroy 정책을 다음 중에 하나를 설정할 수 있다.

정책설명
FailedConnectionOnly유효성 검사에 실패한 Connection만 버린다. (기본값)
AllConnections유효성 검사에 실패한 후 바로 Connection들을 버리는 것이 아니라, 한 번 더 Connection을 Pool에서 가져와서 검사를 요청한다. 만약 검사에 실패하면 그때 Pool에 있는 모든 Connection들을 버린다.

다음은 유효성 검사에 실패한 경우 Pool에 있는 Connection에 대한 Destroy 정책을 설정하는 예이다.

<destroy-policy-on-validation>AllConnections</destroy-policy-on-validation>

참고

유효성 검사 횟수를 추가적으로 더 늘리는 경우에는 <validation-retrial-count>를 이용한다.

Connection Leak 처리

JEUS는 서버 또는 각 Connection Pool별로 Connection Leak에 대한 액션을 설정할 수 있다.

Servlet/JSP, Stateless Session Bean, Message Driven Bean과 같이 시작과 끝이 분명한 컴포넌트의 경우 사용한 Connection을 제대로 반환했는지 확인할 수 있다. 만약 Connection을 반환하지 않았다면 Invocation Manager를 통해서 로깅을 남기거나 강제로 닫아주는 액션을 설정할 수 있다. 단, JCA Connection의 경우 Invocation Manager의 자동 반환(AutoClose) 액션에 대해 예외가 있다.

JCA Connection Pool에서는 JDBC의 java.sql.Connection처럼 어떤 메소드가 close 역할을 하는지 알 수 없기 때문에 일반적으로는 직접 Connection을 닫아주는 것이 불가능하다. 대신 리소스 어댑터의 ra.xml에 설정된 <connection-definition>의 <connection-interface>가 다음과 같은 경우에는 close 메소드의 모양을 이미 알고 있고 메소드에 아무런 파라미터가 없기 때문에 직접 Connection을 닫아준다.

다음은 JCA Connection의 Invocation Manager의 자동 반환 액션의 예외 메소드이다.

  • java.sql.Connection

  • javax.resource.cci.Connection

위의 <connection-interface>가 아닌 경우에는 직접 Connection을 닫아주지 못하지만 javax.resource.spi.ManagedConnection에 정의된 cleanup 메소드를 호출한 뒤 강제로 해당 Connection을 Pool로 반환한다.

cleanup 메소드에는 리소스 어댑터가 다음과 같은 동작을 하도록 정의되어 있다.

The cleanup should invalidate all connection handles
that had been created using this ManagedConnection instance.

본 절에서는 JEUS에서 트랜잭션 타입이 로컬 트랜잭션, 글로벌 트랜잭션인 Connction Pool을 관리하는 방법에 대해서 설명한다.

아웃바운드 리소스 어댑터를 사용해서 하나 또는 그 이상의 아웃바운드 Connection을 설정할 수 있다.

다음은 javax.resource.cci.ConnectionFactory를 Connection Factory를 1개 갖는 ra.xml의 예제이다. 대부분의 경우 Connection Factory는 1개이다.

[예 2.3] Connection Factory가 1개인 경우 Connection Pool 설정 : <<ra.xml>>


jeus-connector-dd.xml을 설정하지 않은 경우에는 ra.xml의 <connection-definition>에 해당하는 Connection Pool을 생성할 수 없다. 그러므로 jeus-connector-dd.xml의 <export-name>을 반드시 설정해야 한다.

다음은 jeus-connector-dd.xml의 설정 예이다. 각 태그에 대해서는 “2.1.4. Connection Pool 설정”을 참고한다.


다음은 javax.sql.DataSource과 javax.resource.cci.ConnectionFactory를 Connection Factory로 설정한 ra.xml 예이다.

[예 2.5] Connection Factory가 2개인 경우 Connection Pool 설정 : <<ra.xml>>

<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://java.sun.com/xml/ns/j2ee" version="1.5"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
        http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd">
    <display-name>ConnectionManagementSample1</display-name>
    <vendor-name>TmaxSoft</vendor-name>
    <eis-type>TestResource</eis-type>
    <resourceadapter-version>2.0</resourceadapter-version>
    <license>
        <license-required>false</license-required>
    </license>
    <resourceadapter>
        <outbound-resourceadapter>
            <connection-definition>
                <managedconnectionfactory-class>
                    com.tmax.DataSourceManagedConnectionFactory
                </managedconnectionfactory-class>
                <connectionfactory-interface>
                    javax.sql.DataSource
                </connectionfactory-interface>
                <connectionfactory-impl-class>
                    com.tmax.JeusDataSource
                </connectionfactory-impl-class>
                <connection-interface>
                    java.sql.Connection
                </connection-interface>
                <connection-impl-class>
                    com.tmax.JeusConnection
                </connection-impl-class>
            </connection-definition>
            <connection-definition>
                <managedconnectionfactory-class>
                    com.tmax.SampleManagedConnectionFactory
                </managedconnectionfactory-class>
                <connectionfactory-interface>
                    javax.resource.cci.ConnectionFactory
                </connectionfactory-interface>
                <connectionfactory-impl-class>
                    com.tmax.SampleConnectionFactory
                </connectionfactory-impl-class>
                <connection-interface>
                    javax.resource.cci.Connection
                </connection-interface>
                <connection-impl-class>
                    com.tmax.SampleConnection
                </connection-impl-class>
            </connection-definition>
            <transaction-support>
                NoTransaction
            </transaction-support>
            <authentication-mechanism>
                <authentication-mechanism-type>
                    BasicPassword
                </authentication-mechanism-type>
                <credential-interface>
                    javax.resource.spi.security.PasswordCredential
                </credential-interface>
            </authentication-mechanism>
            <reauthentication-support>
                false
            </reauthentication-support>
        </outbound-resourceadapter>
    </resourceadapter>
</connector>


다음과 같이 jeus-connector-dd.xml에서 ra.xml의 <connection-definition>에 해당하는 Connection Pool을 생성하려면 반드시 <connectionfactory-interface>를 설정해야 한다. 그렇지 않을 경우 deploy할 때 Connection Pool을 생성할 수 없다는 에러가 발생한다.


JCA Connection Pool의 모니터링 및 제어는 콘솔 툴(jeusadmin) 또는 WebAdmin을 사용한다. JCA Connection Pool의 모니터링 및 제어 방법을 알아보려면 먼저 리소스 어댑터 모듈을 deploy해야 한다. 리소스 어댑터 모듈의 deploy 방법에 대해서는 "JEUS Applications & Deployment 안내서"를 참고한다.

본 절에서 설명하는 예제에는 JCA Connection Pool의 JNDI export name이 'my_rar_cp'인 리소스 어댑터 모듈의 deploy가 완료되었음을 가정한다. JCA Connection Pool의 JNDI export name 설정에 대해서는 “2.1.4. Connection Pool 설정”을 참고한다.

참고

본 절에서는 WebAdmin을 통한 모니터링 및 제어 방법에 대해서 설명한다. 콘솔 툴을 통한 모니터링 및 제어 방법은 JEUS Reference Book”의 “4.2.12. Connection Pool 제어 및 모니터링 명령어”를 참고한다.

다음은 WebAdmin을 사용해서 Connection Pool을 모니터링하는 방법에 대한 설명이다.

  1. WebAdmin의 왼쪽 메뉴에서 [Monitoring] > [Connection Pool]을 선택하면 Connection Pool 화면으로 이동한다. 화면에서 리소스 어댑터 모듈을 deploy한 서버를 선택하면 리소스 어댑터 모듈에 설정한 Connection Pool이 조회된다. 목록의 Connection Pool은 모니터링 정보를 함께 표시한다.


    다음은 Connection Pool 목록의 항목에 대한 설명이다.

    항목설명
    Connection Pool IDJCA Connection Pool의 경우 JNDI export name과 동일하다.
    JNDI Export NameConnection Pool의 JNDI Repository의 등록 이름이다.
    MinConnection Pool의 Connection 최솟값이다.
    MaxConnection Pool의 Connection 최댓값이다.
    Active사용 중인 Connection 개수이다.
    Idle사용 가능한 유휴 Connection 개수이다.
    DisposableConnection Pool에 유휴 Connection이 없는 경우 생성하는 일회용 Connection 개수이다. 일회용 Connection은 Wait 컬럼이 false인 경우에 한해서 생성된다.
    TotalActive, Idle, Disposable의 총합이다.
    WaitConnection Pool에 사용 가능한 유휴 Connection이 없는 경우 일회용 Connection을 생성하여 사용할지의 여부이다.
    EnabledConnection Pool 활성화 여부이다.

  2. 특정 Connection Pool을 클릭하면 해당 Connection Pool에 존재하는 Connection들에 대한 상세 정보를 확인할 수 있다.


    다음은 Connection Pool 상세 정보 항목에 대한 설명이다.

    항목설명
    Connection IDConneciton 식별자이다.
    State

    Connection의 상태이다.

    • idle : 사용 가능한 상태이다.

    • active : 사용 중인 상태이다.

    State TimeState 지속 시간이다.
    Use CountConnection 사용 횟수이다.
    Type

    일회용 Connection인지의 여부를 나타낸다.

    • disposable : 일회용 Connection인 경우를 의미한다.

    • pooled : 일회용 Connection이 아닌 경우를 의미한다.