Search

DBCP

DBCP (Database Connection Pooling)

DB 연결을 ν’€(Pool)을 μ‚¬μš©ν•˜μ—¬, 연결을 μž¬μ‚¬μš©ν•¨μœΌλ‘œμ¨ μ„±λŠ₯을 ν–₯μƒμ‹œν‚€λŠ” 기술
DBCPλ₯Ό μ‚¬μš©ν•˜λ©΄ 맀번 μƒˆλ‘œμš΄ 연결을 μƒμ„±ν•˜μ§€ μ•Šκ³ , 기쑴의 연결을 μž¬μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
DBCP (Database Connection Pooling)
ν’€(Pool)? : μ—¬λŸ¬ μ‚¬λžŒμ΄ ν•¨κ»˜ μ‚¬μš©ν•˜κ³  λ‚˜λˆ„μ–΄ μ“°λŠ” μžμ› μ§‘ν•©
Pool 은 수영μž₯μž…λ‹ˆλ‹€. 수영μž₯μ—λŠ” μ—¬λŸ¬ μ‚¬λžŒμ΄ λ“€μ–΄κ°€μ„œ μˆ˜μ˜ν•˜λ©΄μ„œ λ¬Όμ΄λΌλŠ” μžμ›μ„ κ³΅μœ ν•©λ‹ˆλ‹€. λ§ˆμ°¬κ°€μ§€λ‘œ ν”„λ‘œκ·Έλž¨μ—μ„œμ˜ Pool 은 μžμ›μ„ κ³΅μœ ν•΄μ„œ 효율적으둜 μ‚¬μš©ν•˜λŠ” 방식 μ§€μ›ν•΄μ£ΌλŠ” μ˜μ—­μž…λ‹ˆλ‹€.

DBCP 라이브러리

Apache Commons DBCP

μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 많이 μ‚¬μš©λ˜λŠ” μ—°κ²° ν’€ κ΅¬ν˜„ 라이브러리

λ‹€μš΄λ‘œλ“œ

DBCP μ˜ˆμ‹œ ν”„λ‘œμ νŠΈ

ν”„λ‘œμ νŠΈ ꡬ쑰

DBCP/ β”œβ”€ src/ β”‚ β”œβ”€ DBCP/ β”‚ β”‚ └─ Main.java β”‚ └─ module-info.java └─ lib/ β”œβ”€ commons-dbcp2-2.12.0.jar β”œβ”€ commons-logging-1.3.4.jar β”œβ”€ commons-pool2-2.12.0.jar β”œβ”€ javax.transaction-api-1.3.jar └─ mysql-connector-j-9.5.0.jar
Plain Text
볡사

Main.java (DBCP κΈ°λ³Έ μ˜ˆμ‹œ μ½”λ“œ)

package DBCP; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import org.apache.commons.dbcp2.BasicDataSource; public class Main { public static void main(String[] args) { // BasicDataSource 객체 생성 (DB μ—°κ²° ν’€ μ„€μ •) BasicDataSource ds = new BasicDataSource(); ds.setUrl("jdbc:mysql://localhost:3306/aloha"); ds.setUsername("aloha"); ds.setPassword("123456"); ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); // ν’€ μ„€μ • ds.setInitialSize(5); // 초기 μ—°κ²° 개수 ds.setMaxTotal(10); // μ΅œλŒ€ μ—°κ²° 개수 try (Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM board")) { while (rs.next()) { System.out.println("제λͺ©: " + rs.getString("title")); System.out.println("μž‘μ„±μž: " + rs.getString("writer")); System.out.println("λ‚΄μš©: " + rs.getString("content")); System.out.println("------"); } } catch (Exception e) { e.printStackTrace(); } } }
Java
볡사

module-info.java

module DBCP { requires java.sql; requires static java.transaction.xa; requires org.apache.commons.dbcp2; requires org.apache.commons.pool2; }
Java
볡사

SQL

-- λ°μ΄ν„°λ² μ΄μŠ€ 생성 CREATE DATABASE aloha; -- ν…Œμ΄λΈ” 생성 -- κ²Œμ‹œνŒ ν…Œμ΄λΈ” 생성 CREATE TABLE `aloha`.`board` ( `no` INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '번호', `title` VARCHAR(100) NOT NULL COMMENT '제λͺ©', `writer` VARCHAR(100) NOT NULL COMMENT 'μž‘μ„±μž', `content` TEXT NULL COMMENT 'λ‚΄μš©', `created_at` TIMESTAMP NOT NULL DEFAULT now() COMMENT 'λ“±λ‘μΌμž', `updated_at` TIMESTAMP NOT NULL DEFAULT now() COMMENT 'μˆ˜μ •μΌμž' ) COMMENT = 'κ²Œμ‹œνŒ'; -- 데이터 μΆ”κ°€ INSERT INTO board (title, writer, content) VALUES ('제λͺ©01', 'μž‘μ„±μž01', 'λ‚΄μš©01'), ('제λͺ©02', 'μž‘μ„±μž02', 'λ‚΄μš©02'), ('제λͺ©03', 'μž‘μ„±μž03', 'λ‚΄μš©03'), ('제λͺ©04', 'μž‘μ„±μž04', 'λ‚΄μš©04'), ('제λͺ©05', 'μž‘μ„±μž05', 'λ‚΄μš©05') ;
SQL
볡사

DBCP κ΄€λ ¨ 라이브러리 μ—­ν•  정리

라이브러리 파일λͺ…
μ£Όμš” μ—­ν• 
ν•„μˆ˜ μ—¬λΆ€
commons-dbcp2-2.12.0.jar
핡심 DBCP 라이브러리. BasicDataSource, 컀λ„₯μ…˜ ν’€ 관리, 컀λ„₯μ…˜ μž¬μ‚¬μš©/회수 κΈ°λŠ₯ 제곡
ν•„μˆ˜
commons-pool2-2.12.0.jar
객체 ν’€(Object Pool) κ΅¬ν˜„ 라이브러리. DBCPκ°€ λ‚΄λΆ€μ μœΌλ‘œ 컀λ„₯μ…˜μ„ 관리할 λ•Œ μ‚¬μš©
ν•„μˆ˜
commons-logging-1.3.4.jar
Apache 곡용 λ‘œκΉ… 라이브러리. DBCP λ‚΄λΆ€ λ™μž‘ 둜그λ₯Ό ν‘œμ€€ λ‘œκΉ… μΈν„°νŽ˜μ΄μŠ€λ‘œ 좜λ ₯
선택(ꢌμž₯)
javax.transaction-api-1.3.jar
νŠΈλžœμž­μ…˜ κ΄€λ ¨ API (JTA). DBCP λ‚΄λΆ€μ—μ„œ νŠΈλžœμž­μ…˜ 연동 μ‹œ ν•„μš”
선택(λͺ¨λ“ˆ μ‚¬μš© μ‹œ ν•„μˆ˜)
mysql-connector-j-9.0.0.jar
MySQL JDBC λ“œλΌμ΄λ²„. μ‹€μ œ DB 연결을 μœ„ν•œ ν•„μˆ˜ λ“œλΌμ΄λ²„
ν•„μˆ˜

μž‘λ™ 흐름 μš”μ•½

단계
λ™μž‘
μ£Όμš” 클래슀
β‘ 
BasicDataSource 생성
BasicDataSource
β‘‘
DB μ—°κ²° 정보 μ„€μ • (URL, user, password, driver)
BasicDataSource
β‘’
초기 컀λ„₯μ…˜ ν’€ 생성 (setInitialSize)
GenericObjectPool (λ‚΄λΆ€)
β‘£
getConnection() 호좜 μ‹œ ν’€μ—μ„œ μ—°κ²° 제곡
PoolableConnectionFactory
β‘€
μ‚¬μš© ν›„ μžλ™μœΌλ‘œ λ°˜ν™˜ (try-with-resources μ‚¬μš©)
Connection.close() λ‚΄λΆ€μ—μ„œ λ°˜ν™˜

DBCP 컀λ„₯μ…˜ ν’€ ꡬ쑰도

graph TB
    subgraph Application["μ• ν”Œλ¦¬μΌ€μ΄μ…˜"]
        A["ν”„λ‘œκ·Έλž¨ μ½”λ“œ"]
    end
    
    subgraph DBCP["DBCP (Connection Pool)"]
        B["BasicDataSource"]
        C["GenericObjectPool"]
        D["Active Connections<br/>(μ‚¬μš© 쀑인 μ—°κ²°)"]
        E["Idle Connections<br/>(λŒ€κΈ° 쀑인 μ—°κ²°)"]
    end
    
    subgraph Database["λ°μ΄ν„°λ² μ΄μŠ€"]
        F["MySQL/Oracle/PostgreSQL λ“±"]
    end
    
    A -->|"1. getConnection() μš”μ²­"| B
    B -->|"2. μ—°κ²° μš”μ²­"| C
    C -->|"3. μ‚¬μš© κ°€λŠ₯ν•œ μ—°κ²° 확인"| E
    E -->|"4. μ—°κ²° 제곡"| D
    D -->|"5. Connection λ°˜ν™˜"| A
    A -->|"6. 쿼리 μ‹€ν–‰"| F
    F -->|"7. κ²°κ³Ό λ°˜ν™˜"| A
    A -->|"8. close() 호좜<br/>(μ—°κ²° λ°˜ν™˜)"| D
    D -->|"9. ν’€λ‘œ λ°˜ν™˜"| E
    
    C -.->|"μ΅œλŒ€ μ—°κ²° 수<br/>초과 μ‹œ λŒ€κΈ°"| C
    E -.->|"InitialSize: 5<br/>MaxTotal: 10"| E
    
    style A fill:#e1f5ff
    style B fill:#fff4e6
    style C fill:#fff4e6
    style D fill:#ffe6e6
    style E fill:#e6ffe6
    style F fill:#f0e6ff
Mermaid
볡사

ꡬ쑰도 μ„€λͺ…

β€’
Application (μ• ν”Œλ¦¬μΌ€μ΄μ…˜): ν”„λ‘œκ·Έλž¨ μ½”λ“œμ—μ„œ DB 연결이 ν•„μš”ν•  λ•Œ DBCP에 μš”μ²­
β€’
BasicDataSource: DBCP의 핡심 클래슀둜, μ—°κ²° 풀을 κ΄€λ¦¬ν•˜λŠ” μ§„μž…μ 
β€’
GenericObjectPool: μ‹€μ œ 컀λ„₯μ…˜ 객체듀을 ν’€(Pool)둜 κ΄€λ¦¬ν•˜λŠ” λ‚΄λΆ€ ꡬ쑰
β€’
Idle Connections (λŒ€κΈ° μ—°κ²°): μ‚¬μš©λ˜μ§€ μ•Šκ³  ν’€μ—μ„œ λŒ€κΈ° 쀑인 μ—°κ²°λ“€
InitialSize: μ΄ˆκΈ°μ— μƒμ„±λ˜λŠ” μ—°κ²° 개수
MaxTotal: ν’€μ—μ„œ μœ μ§€ν•  수 μžˆλŠ” μ΅œλŒ€ μ—°κ²° 개수
β€’
Active Connections (ν™œμ„± μ—°κ²°): ν˜„μž¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ‚¬μš© 쀑인 μ—°κ²°λ“€
β€’
μ—°κ²° 흐름:
1.
getConnection() 호좜 β†’ ν’€μ—μ„œ μ—°κ²° κ°€μ Έμ˜€κΈ°
2.
DB 쿼리 μ‹€ν–‰
3.
close() 호좜 β†’ 연결을 ν’€λ‘œ λ°˜ν™˜ (μ‹€μ œλ‘œ λ‹«μ§€ μ•Šκ³  μž¬μ‚¬μš©)