6.2. JDBC 데이터 소스 개요
JDBC 1.4 표준에는 java.sql.Connection
개체의 팩토리 역할을 하는 javax.sql.DataSource
인터페이스가 도입되었습니다. 일반적으로 이러한 데이터 소스는 JNDI 레지스트리에 바인딩되어 있고 서블릿 또는 Clevis와 같은 Java EE 구성 요소에 있거나 삽입되었습니다. 주요 측면은 이러한 데이터 소스가 애플리케이션 서버 내에 구성되고 배포된 애플리케이션에서 이름별로 참조 된다는 것입니다.
다음 연결 오브젝트에는 자체 데이터 소스가 있습니다.
데이터 소스 | 연결 |
---|---|
|
|
|
|
|
|
위의 각 데이터 소스 의 가장 중요한 차이점은 다음과 같습니다.
javax.sql.DataSource
는java.sql.Connection
인스턴스를 가져오기 위한 것과 같은 팩토리입니다. 대부분의javax.sql.DataSource
구현이 일반적으로 연결 풀링 을 수행한다는 사실은 이미지를 변경하지 않아야 합니다. 애플리케이션 코드에서 사용해야 하는 유일한 인터페이스입니다. 다음 중 어느 것을 구현했는지는 중요하지 않습니다.- 직접 JDBC 액세스
-
JPA 지속성 유닛 구성(<
jta-data-source
> 또는 <non-jta-data-source
> ) - Apache Camel 또는 Spring Framework와 같은 널리 사용되는 라이브러리
javax.sql.ConnectionPoolDataSource
는 가장 중요한 것은 일반(비 데이터베이스별) 연결 풀/데이터 소스와 데이터베이스별 데이터 소스 간의 브릿지 입니다. SPI 인터페이스로 취급될 수 있습니다. 애플리케이션 코드는 일반적으로 JNDI에서 가져와 애플리케이션 서버에서 구현한 일반적인javax.sql.DataSource
개체를 처리합니다(commons-dbcp2
와 같은 라이브러리를 사용). 애플리케이션 코드는javax.sql.ConnectionPoolDataSource
와 직접 상호 작용하지 않습니다. 애플리케이션 서버와 데이터베이스별 드라이버 간에 사용됩니다. 다음 시퀀스 다이어그램에서는 다음을 보여줍니다.
javax.sql.XADataSource
는javax.sql.XAConnection
및javax. Cryostat.xa.XAResource
를 얻는 방법입니다.javax.sql.ConnectionPoolDataSource
와 동일하며 애플리케이션 서버와 데이터베이스별 드라이버 간에 사용됩니다. 다음은 JTA 트랜잭션 관리자를 포함하여 다른 행위자와 함께 약간 수정된 다이어그램입니다.
위의 두 다이어그램에 표시된 대로 javax.sql.DataSource
및 javax. Cryostat.UserTransaction
인스턴스를 구성할 수 있는 일반화된 엔터티인 App Server 와 상호 작용합니다. 이러한 인스턴스는 JNDI를 통해 또는 CDI 또는 다른 종속성 메커니즘을 사용하여 주입하여 액세스할 수 있습니다.
중요한 점은 애플리케이션이 XA 트랜잭션 및/또는 연결 풀링을 사용하는 경우에도 애플리케이션은 다른 두 JDBC 데이터 소스 인터페이스가 아닌 javax.sql.DataSource
와 상호 작용한다는 것입니다.
6.2.1. 데이터베이스 특정 및 일반 데이터 소스
JDBC 데이터 소스 구현은 다음 두 가지 범주로 분류됩니다.
다음과 같은 일반적인
javax.sql.DataSource
구현- Apache Commons DBCP(2)
- Apache Tomcat JDBC (DBCP 기반)
-
javax.sql.DataSource
,javax.sql.XADataSource
및javax.sql.ConnectionPoolDataSource
의 데이터베이스 특정 구현
일반적인 javax.sql.DataSource
구현이 자체적으로 데이터베이스별 연결을 만들 수 없다는 혼동을 줄 수 있습니다. 일반 데이터 소스에서 java.sql.Driver.connect()
또는 java.sql.DriverManager.getConnection()
을 사용할 수 있는 경우에도 일반적으로 데이터베이스별 javax.sql.DataSource
구현을 사용하여 이 일반 데이터 소스를 구성하는 것이 좋습니다.
일반 데이터 소스가 JTA와 상호 작용하려면 javax.sql.XADataSource
의 데이터베이스별 구현으로 구성해야 합니다.
작업을 종료하기 위해 일반적인 데이터 소스에 는 일반적으로 연결 풀링을 수행하기 위해 javax.sql.ConnectionPoolDataSource
의 데이터베이스별 구현이 필요하지 않습니다. 기존 풀은 일반적으로 표준 JDBC 인터페이스(javax.sql.ConnectionPoolDataSource
및 javax.sql.PooledConnection
) 없이 풀링을 처리하고 대신 자체 사용자 지정 구현을 사용합니다.
6.2.2. 일부 일반 데이터 소스
잘 알려진 일반적인 데이터 소스인 Apache Commons DBCP(2) 샘플을 고려해 보십시오.
javax.sql.XADataSource 구현
DBCP2에는 예상되는 javax.sql.XADataSource
의 구현이 포함되어 있지 않습니다.
javax.sql.ConnectionPoolDataSource implementations
DBCP2 에는 javax.sql.ConnectionPoolDataSource
:org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS
의 구현이 포함됩니다. java.sql.DriverManager.getConnection()
을 호출하여 javax.sql.PooledConnection
개체를 생성합니다. 이 풀은 직접 사용해서는 안되며 다음과 같은 드라이버의 어댑터 로 취급해야 합니다.
-
자체
javax.sql.ConnectionPoolDataSource
구현을 제공하지 마십시오. - 연결 풀에 대한 JDBC 권장 사항에 따라 사용하려고 합니다.
위의 시퀀스 다이어그램에 표시된 대로 드라이버는 javax.sql.ConnectionPoolDataSource
를 직접 또는 org.apache.commons.dbcp2.cpds adapter.DriverAdapterCPDS
어댑터의 도움을 받아 직접 또는 DBCP2는 다음과 같은 애플리케이션 서버 계약을 구현합니다.
-
org.apache.commons.dbcp2.datasources.PerUserPoolDataSource
-
org.apache.commons.dbcp2.datasources.SharedPoolDataSource
두 풀 모두 구성 단계에서 javax.sql.ConnectionPoolDataSource
의 인스턴스를 사용합니다.
DBCP2에서 가장 중요하고 흥미로운 부분입니다.
javax.sql.DataSource 구현
연결 풀링 기능을 구현하려면 JDBC 권장 사항을 따라 javax.sql.ConnectionPoolDataSource
javax.sql.PooledConnection
SPI를 사용할 필요가 없습니다.
다음은 DBCP2의 일반 데이터 소스 목록입니다.
-
org.apache.commons.dbcp2.BasicDataSource
-
org.apache.commons.dbcp2.managed.BasicManagedDataSource
-
org.apache.commons.dbcp2.PoolingDataSource
-
org.apache.commons.dbcp2.managed.ManagedDataSource
여기에는 두 개의 축이 있습니다.
기본 및 풀링
이 축 은 풀링 구성 측면을 결정합니다.
두 종류의 데이터 소스 모두 java.sql.Connection
개체의 풀링 을 수행합니다. 유일한 차이점은 다음과 같습니다.
-
기본 데이터 소스는
org.apache.commons.pool2.impl.GenericObjectPool
의 내부 인스턴스를 구성하는 데 사용되는maxTotal
또는minIdle
과 같은 8080 속성을 사용하여 구성됩니다. -
풀링 데이터 소스는 외부에서 생성/구성된
org.apache.commons.pool2.ObjectPool
로 구성됩니다.
Managed vs non-managed
이 축 은 연결 생성 측면과 JTA 동작을 결정합니다.
관리되지 않는 기본 데이터 소스는 내부적으로
java.sql.Driver.connect()
를 사용하여java.sql.Connection
인스턴스를 생성합니다.관리되지 않는 풀링 데이터 소스는 전달된
org.apache.commons.pool2.ObjectPool
개체를 사용하여java.sql.Connection
인스턴스를 생성합니다.관리되는 풀링 데이터 소스는
org.apache.commons.dbcp2.managed.ManagedConnection
개체 내에서java.sql.Connection
인스턴스를 래핑하여 JTA 컨텍스트에서 필요한 경우javax. Cryostat.Transaction.enlistResource()
가 호출되도록 합니다. 그러나 여전히 래핑된 실제 연결은 풀이 구성된 모든org.apache.commons.pool2.ObjectPool
개체에서 가져옵니다.관리형 기본 데이터 소스를 사용하면 전용
org.apache.commons.pool2.ObjectPool
을 구성할 수 없습니다. 대신 기존의 실제 데이터베이스별javax.sql.XADataSource
개체를 구성하는 것으로 충분합니다. Cryostat 속성은org.apache.commons.pool2.impl.GenericObjectPool
의 내부 인스턴스를 생성하는 데 사용되며, 이 인스턴스는 관리되는 풀링 데이터 소스(org.apache.commons.dbcp2.managed.ManagedDataSource
)의 내부 인스턴스에 전달됩니다.
DBCP2에서 할 수 없는 유일한 것은 XA 트랜잭션 복구 입니다. DBCP2는 활성 JTA 트랜잭션에 XAResources를 올바르게 등록하지만 복구를 수행하지 않습니다. 이 작업은 별도로 수행해야 하며 구성은 일반적으로 선택한 트랜잭션 관리자 구현(예: 네레이나 )에 따라 다릅니다.
6.2.3. 사용할 패턴
권장 패턴은 다음과 같습니다.
-
연결/XA 연결을 생성할 수 있는 데이터베이스별
javax.sql.DataSource
또는javax.sql.XADataSource
인스턴스(URL, 인증 정보 등)를 생성하거나 가져옵니다. -
데이터베이스별 구성(연결 풀링, 트랜잭션 관리자 등)을 사용하여 데이터베이스 별
javax.sql.DataSource
인스턴스(위의 데이터베이스별 데이터 소스로 내부 구성)를 생성하거나 가져옵니다. -
javax.sql.DataSource
를 사용하여java.sql.Connection
의 인스턴스를 가져오고 JDBC 작업을 수행합니다.
다음은 표준 예입니다.
// Database-specific, non-pooling, non-enlisting javax.sql.XADataSource PGXADataSource postgresql = new org.postgresql.xa.PGXADataSource(); // Database-specific configuration postgresql.setUrl("jdbc:postgresql://localhost:5432/reportdb"); postgresql.setUser("fuse"); postgresql.setPassword("fuse"); postgresql.setCurrentSchema("report"); postgresql.setConnectTimeout(5); // ... // Non database-specific, pooling, enlisting javax.sql.DataSource BasicManagedDataSource pool = new org.apache.commons.dbcp2.managed.BasicManagedDataSource(); // Delegate to database-specific XADatasource pool.setXaDataSourceInstance(postgresql); // Delegate to JTA transaction manager pool.setTransactionManager(transactionManager); // Non database-specific configuration pool.setMinIdle(3); pool.setMaxTotal(10); pool.setValidationQuery("select schema_name, schema_owner from information_schema.schemata"); // ... // JDBC code: javax.sql.DataSource applicationDataSource = pool; try (Connection c = applicationDataSource.getConnection()) { try (Statement st = c.createStatement()) { try (ResultSet rs = st.executeQuery("select ...")) { // ....
Fuse 환경에는 많은 구성 옵션이 있으며 DBCP2를 사용할 필요가 없습니다.