208. 환경 (Environments)

2012. 4. 20. 09:23공부/MYBATIS

마이바티스는 다중환경으로 설정될 수 있어. 이는 다양한 이유로 다수의 데이터베이스에 SQL 매핑을  적용할 수 있게 해주지. 예를 들면, 개발환경, 테스트 환경, 실제 환경을 각기 다르게 설정할 수 있고, 동일 스키마를 공유하는 다수의 데이터베이스를 지원한다거나, 동일한 SQL 매핑을 사용하고 싶을 수도 있어. 암튼 수많은 경우가 있어.

그렇지만, 기억해야할 한 가지 중요한 것 : 다중 환경을 설정할 수 있지만, SQLSessionFactory 인스턴스 당 오직 하나만 선택할 수 있어.

따라서 두 개의 데이터베이스에 연결하고 싶다면, SqlSessionFactory를 각각 하나씩 두개를 생성할 필요가 있어. 3개의 데이터베이스라면, 3개의 인스턴스가 필요하고, 더 연결하고 싶다면 더 필요하겠지. 참 기억하기 쉽죠 잉~

- 데이터베이스당 하나의 SqlSessionFactory 인스턴스

빌드하기 위한 환경을 기술하기 위해, 간단하게 옵션으로 파라미터를 SqlSessionFactoryBuilder에 전달해. 이 환경을 만족시키는 두가지 특징은..

SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment,properties);

환경이 생략되면, 기본환경이 로딩되지. 다음처럼

SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader,properties);

environments 요소는 환경이 설정되는 방법을 정의한다.

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

주요 부분의 주목하자.

  • The default Environment ID (e.g. default="development").
  • The Environment ID for each environment defined (e.g. id="development").
  • The TransactionManager configuration (e.g. type="JDBC")
  • The DataSource configuration (e.g. type="POOLED")

기본환경과 환경ID는 그 이름 자체로 설명되지. 뭐가 좋든간에 이름은 그들중 하나에 기본적으로 매칭됨을 확신해.


트랜잭션매니저

마이바티스에 의해 포함되는 두 개의 트랜잭션매니저 타입이 있어 (type="[JDBC|MANAGED]")

  • JDBC – 이 설정은 JDBC의 커밋/롤백 기능을 직접적으로 사용하게 해. 트랜잭션의 범위를 관리하기 위한 데이터소스로부터 찾아온 컨넥션에 의존해
  • MANAGED – 이 설정은 거의 아무것도 안해. 절대 컨넥션을 커밋하지도 않고, 롤백하지도 않아.  대신, 컨테이너가 트랜잭션의 전체 생명주기를 관리하도록 하지 (예. a JEE Application Server context). 이것은 기본적으로 컨넥션을 닫아. 하지만, 일부 컨테이너에서 이것이 이루어진다고 예측할수 없기 때문에, 컨넥션을 닫기를 멈출 필요가 있다면, "closeConnection" 프라퍼티를 false로 설정해. 예를 들면,

    <transactionManager type="MANAGED">
      <property name="closeConnection" value="false"/>
    </transactionManager>

NOTE 스프링과 함께 마이바티스를 사용할 계획이라면, 어떠한 트랜잭션매니저도 설정할 필요가 없어. 왜냐하면, 스프링 모듈이 미리 세팅된 어떠한 설정이라도 오버라이딩한 하나를 세팅하거든.

이들 트랜잭션매니저 타입은 아무런 프라퍼티도 필요치 않아. 그들은 둘다 타입알리아스이고, 다르게 말하면, 그것들을 사용하는 대신, 풀 클래스네임이나 TransactionFactory 인터페이스의 구현체(implementation)를 참조하는 타입알리아스를 쓸 수 있어.

public interface TransactionFactory {
  void setProperties(Properties props);  
  Transaction newTransaction(Connection conn);
  Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);  
}

XML에 설정된 모든 프라퍼티들은 인스턴스가 만들어진 즉시, setProperties() 메소드로 전달될거야. 구현체는 또한 트랜잭션 구현체를 생성할 필요가 있고, 이것 또한 매우 간단한 인터페이스야

public interface Transaction {
  Connection getConnection() throws SQLException;
  void commit() throws SQLException;
  void rollback() throws SQLException;
  void close() throws SQLException;
}

두 인터페이스를 사용해서, 마이바티스가 어떻게 트랜잭션을 다룰지를 완벽하게 만들 수 있어.

데이터소스

데이터소스 요소는 표준 JDBC 데이터소스 인터페이스를 이용해서 JDBC 컨넥션 객체의 소스를 설정해

- 대부분의 마이바티스 어플리케이션은 데이터소스를 예제와 같이 설정해. 필요한건 아니지만, 사실 그렇다고 할지라도, 늦은 로딩이 가능하기 위해, 이 데이터소스가 필요해

세가지 내장 데이터소스 타입이 있어 ( 즉 type="????" )

UNPOOLED - 이 데이터소스의 구현체는 컨넥션이 요청될때마다 간단하게  열고 닫아. 조금 느린 반면에 즉시 사용가능한 컨넥션 수준의 퍼포먼스가 필요한 어플리케이션이 아닌 간단한 어플리케이션에는  좋은 선택이야. 각기 다른 데이터베이스는 각기 다른 퍼포먼스 영역이야. 그래서 일부 풀이 덜 중요한 케이스에는 이 설정이 이상적이야. UNPOOLED 데이터소스는 5가지 프라퍼티로 설정돼.

  • driver – JDBC 드라이버의 풀 클래스 네임 (NOT of the DataSource class if your driver includes one).
  • url – 데이터베이스 인스턴스에 대한 JDBC URL 
  • username – 로그인을 위한 데이터베이스 username
  • password -  로그인을 위한 데이터베이스 password 
  • defaultTransactionIsolationLevel – 컨넥션을 위한 기본 트랜잭션 분리 레벨

선택적으로, 프라퍼티를 데이터베이스 드라이버로 전달할 수 있어. 이걸 하려면, 프라퍼티 접두어를 drive. 으로 하면 돼. 예를 들면

driver.encoding=UTF8

이것은 UTF8 값을 가진 encoding 프라퍼티를 DriverManager.getConnection(url, driverProperties) 메소드를 통해 데이터베이스 드라이버로 전달해. 

POOLED - 이 데이터소스 구현체는 데이터베이스 컨넥션 초기화와 새로운 컨넥션 인스턴스를 생성하기 위해 필요한 인증 시간과 초기화를 피하기 위해  JDBC 컨넥션 객체를 풀로 만든다.이 방법은 동시에 수행되는 웹 어필리케이션들이 빠른 응답시간을 확보하기 위해 널리 애용되는 접근방법이다.

UNPOOLED에서 사용된 프라퍼티 외에도 POOLED 데이터소스를 설정하기 위한 수 많은 프라퍼티가  있다.

  • poolMaximumActiveConnections – 어떤 시간에 존재하는 활성화된 컨넥션의 숫자(즉, 사용되는) 기본값: 10
  • poolMaximumIdleConnections – 어떤 시간에 쉬고 있는 컨넥션의 숫자
  • poolMaximumCheckoutTime –  풀의 컨넥션이 강제로 리턴되기 위한 "check out"시간. 기본값: 20000ms (즉. 20초)
  • poolTimeToWait – 컨넥셔을 취득하려는 시간이 비정상적으로 긴 경우 재시도를 하고 로그상태를 기록할  수 있는 기회를 풀에게 주는 저수준 세팅 (풀이 잘못설정되었을경우 실패를 조용하고 영원히 회피하기 위해). 기본값: 20000ms (즉. 20초)
  • poolPingQuery – 데이터베이스가 정상적인지 컨넥션이 잘 작동하는지와 요청을 받아들일 준비가 되어있는지를 입증하기 위해 데이터베이스로 보내는 핑 쿼리. 기본값은 "NO PING QUERY SET" 이고, 대부분의 데이터베이스에 적절한 에러메시지를 가진 실패를 초래함.
  • poolPingEnabled – 필 쿼리를 사용할지를 결정. 만약 enabled 이면, 유효한(가급적 매우 빠른) poolPingQuery 프라퍼티도 꼭 설정해야 함. 기본값: false.
  • poolPingConnectionsNotUsedFor – 이 설정은 poolPingQuery가 얼마나 자주 사용될 것인지 설정해. 이건 불필요한 핑을 피하기 위해 데이터베이스 컨넥션을 위한 일반적인 timeout과 같게 설정될 수 있어. 기본값: 0 (즉 모든 컨넥션이 매번 핑을 때림 – 단,  poolPingEnabled 값이 true 일 때만 ).

JNDI - 이 데이터소스의 구현체는 EJB와 같은 컨테이너나 중앙에서 데이터소스를 설정하는 어플리케이션 서버나 JNDI 컨텍스트에 대한 참조로 사용되기 위한 것이다. 이 데이터소스 설정은 오직 2개의 프라퍼티를 필요로 한다.

  • initial_context – 이 프라퍼티는 InitialContext로부터 Context 검색을 위해 사용돼. (즉. initialContext.lookup(initial_context) ). 이 프라퍼티는 선택사항이야. 생략되면 InitailContext를 직접 검색되는 대신에 data_source 프라퍼티가 검색될거야.
  • data_source – 이것은 데이터소스가 발견될 수 있는 인스턴스에 대한 context 경로야. Initial_context 검색에 의한 context 리턴이나, Initial_context가 제공되지 않았을 경우 직접적인 Initial_context 대신에 검색될거야.

다른 데이터소스 설정과 비슷하게 프라퍼티를 env. 접두사를 붙여서 직접 InitialContext로  전달하는 것이 가능하다. 예를 들면

env.encoding=UTF8

이것은 UTF8 값을 가진 encoding 프라퍼티를 InitialContext가 초기화 될 때, 생성자로 전달한다.