JiwonDev

JDBC Connection ์— ๋Œ€ํ•œ ์ดํ•ด, HikariCP ์„ค์ • ํŒ

by JiwonDev

JDBC๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•„์˜ˆ ๋ชจ๋ฅธ๋‹ค๋ฉด [10๋ถ„ ํ…Œ์ฝ”ํ†ก] ์ฝ”์ฝ”๋‹ฅ์˜ JDBC ์˜์ƒ์„ ํ•œ๋ฒˆ ๋ณด๊ณ  ์˜ค์‹œ๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค.

 

 

 

 

๐Ÿ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์‹œ์ž‘์€ ๊ฒฐ๊ตญ JDBC 

๋”๋ณด๊ธฐ

JVM์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์Šคํ”„๋ง์ด๊ฑด JPA๋ฅผ ์“ฐ๊ฑด ๊ฒฐ๊ตญ ๋งˆ์ง€๋ง‰์—” JDBC (Java Database Connectivity API)๋ฅผ ์ด์šฉํ•˜์—ฌ DB ์™€ ํ†ต์‹ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ JDBC Driver๋Š” ์ธํ„ฐํŽ˜์ด์Šค ์ผ ๋ฟ ์‹ค์ œ ๊ตฌํ˜„์ฒด๋Š” ๊ณต์‹ DB ๋ฒค๋”์‚ฌ(Oracle, MS..)์—์„œ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‚˜๋งŒ์˜ Driver๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋™์ผํ•˜๊ฒŒ JDBC Driver ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋“ฑ๋กํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

try {
    // JDBC 4.0 ๋ถ€ํ„ฐ๋Š” META-INF/services/java.sql.Driver๋ฅผ ์ฝ์–ด DriverManager๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.
    // ๋ฌผ๋ก  Class.forName("com.mysql.cj.jdbc.Driver") ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ง์ ‘ DriverManager์— ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
    connection = DriverManager.getConnection(jdbcUrl, username, password)
    println("Database connection established.")

    // Statement ์ƒ์„ฑ
    statement = connection.createStatement()

    // SQL ์ฟผ๋ฆฌ ์‹คํ–‰
    val sql = "SELECT * FROM your_table"
    resultSet = statement.executeQuery(sql)

    // ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ
    while (resultSet.next()) {
        // ์ฒซ ๋ฒˆ์งธ ์ปฌ๋Ÿผ ๊ฐ’์„ String์œผ๋กœ ์ฝ๊ธฐ
        val firstColumnValue = resultSet.getString(1)
        println(firstColumnValue)
    }
} catch (e: Exception) {
    e.printStackTrace()
} finally {
    // DB ์ปค๋„ฅ์…˜์„ ๋‹ซ์•„์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. Java7 ๋ถ€ํ„ฐ๋Š” try-resource ๋ฌธ (kotlin ์—์„  use)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธํ•ฉ๋‹ˆ๋‹ค.
    resultSet?.close()
    statement?.close()
    connection?.close()
}

 

 

 

๐Ÿ€ DB ํŠธ๋žœ์žญ์…˜์€ ์–ด๋–ป๊ฒŒ ๊ฑฐ๋Š” ๊ฑธ๊นŒ์š”?

๋Œ€๋ถ€๋ถ„์˜ DBMS ๋Š” AutoCommit ํŠธ๋žœ์žญ์…˜ ๋ชจ๋“œ์™€ ๋ช…์‹œ์ ์ธ ํŠธ๋žœ์žญ์…˜ ๋ชจ๋“œ(BEGIN-COMMIT-ROLLBACK) ๋‘˜ ๋‹ค ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‹น์—ฐํ•œ๊ฑฐ์ง€๋งŒ DB์—์„œ ๋ชจ๋“  ์ž‘์—…์€ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜์„ ๊ฑธ์ง€ ์•Š์•˜๋”๋ผ๋„ AutoCommit์— ์˜ํ•ด ์ž‘์—… ์™„๋ฃŒ ํ›„ Commit์ด ์‹คํ–‰ ๋ฉ๋‹ˆ๋‹ค.

 

JDBC์˜ ๊ฒฝ์šฐ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•  ๋•Œ ๋ณ„๋„์˜ API, ์˜ˆ๋ฅผ ๋“ค์–ด BeginTransaction() ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ๋”ฐ๋กœ ์ œ๊ณตํ•˜์ง€์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  Connection.setAutoCommit(false) ๋ฅผ ์ด์šฉํ•ด ํŠธ๋žœ์žญ์…˜์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

์ด ๋•Œ ํ•œ๊ฐ€์ง€ ์œ ์˜ํ•ด์•ผํ•  ์ ์€, setAutoCommit์„ ๋ฐ”๊ฟ€ ๋•Œ JDBC ๋‚ด๋ถ€์—๋งŒ ๋š-๋”ฑ ์ ์šฉ๋˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ DBMS์— ์ฟผ๋ฆฌ๋กœ ์š”์ฒญํ•ด์•ผํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฌด์˜๋ฏธํ•˜๊ฒŒ ๊ณ„์† ๋ณ€๊ฒฝํ•œ๋‹ค๋ฉด ํ•„์š” ์ด์ƒ์˜ ํŠธ๋ž˜ํ”ฝ๊ณผ DB ๋ถ€ํ•˜๊ฐ€ ๋ฐœ์ƒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์Šคํ”„๋ง์„ ์“ด๋‹ค๋ฉด DataSourceTranscationManager ์—์„œ ์ด๋ฏธ ์ตœ์ ํ™” ๋˜์–ด์žˆ๊ณ  HikariDataSource ์—์„œ๋„ autoCommit์„ ๊ด€๋ฆฌํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹ ๊ฒฝ ์“ธ ์ผ์€ ์—†๊ธดํ•ฉ๋‹ˆ๋‹ค.

BEGIN(deferred)๋Š” ์‹ค์ œ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ ์š”์ฒญ์„ ํ•˜๋Š” ์‹œ์ ์— "BEGIN" ์„ ์ „์†กํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

 

 

๋งŒ์•ฝ Reader, Writer DB๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๊ธฐ๋ณธ๊ฐ’์„ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •ํ•ด์ฃผ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

spring:
  datasource:
    maindb:
      writer:
        driver-class-name: org.postgresql.Driver
        auto-commit: false # writer๋Š” ์ง์ ‘ ํŠธ๋žœ์žญ์…˜์„ ๊ฑธ์ผ์ด ๋งŽ์œผ๋‹ˆ ๊ธฐ๋ณธ๊ฐ’ false
        connection-timeout: 3000
      reader:
        driver-class-name: org.postgresql.Driver
        auto-commit: true # read-only๋Š” ํŠธ๋žœ์žญ์…˜์„ ๊ฑธ ์ผ์ด ์—†์œผ๋‹ˆ ๊ธฐ๋ณธ๊ฐ’ true
        connection-timeout: 3000

 

 

 

๐Ÿ€ JDBC API๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ์š”?

JDBC API ๋ฅผ ์ž์„ธํ•˜๊ฒŒ ์‚ดํŽด๋ณด๋ฉด ํฌ๊ฒŒ JDBC Driver์™€ DataSource๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ Repository(DAO, Data Access Object)๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

  • JDBC Driver ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • DataSource ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ฐ์ข… ์„ค์ • ๋ฐ ์ปค๋„ฅ์…˜ ํ’€์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • ์ฐธ๊ณ ๋กœ ์•„๋ฌด๋Ÿฐ ์„ค์ •์—†์ด ์—ฐ์Šต์šฉ์œผ๋กœ ๋‹จ์ˆœ ์—ฐ๊ฒฐ์„ ํ•ด๋ณผ ๋•Œ๋Š” DataSource ๋Œ€์‹  DriverManager ๋ฅผ  ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. 

์ด๋ฏธ์ง€ ์ถœ์ฒ˜ https://netmarble.engineering/jdbc-timeout-for-game-server

 

- JDBC Driver 

DriverManager์— ๋“ฑ๋ก๋œ ํด๋ž˜์Šค๋“ค์€ JDBC Driver ๊ตฌํ˜„์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ static {...} ์œผ๋กœ ๋Ÿฐํƒ€์ž„์— ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค.

 ์ž๋ฐ”์—์„œ Driver ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€์•Š๊ณ  DataSource๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉํ•˜๋ฉฐ ์ด๋Š” ํŠน์ • DB์™€ ์‹ค์งˆ์ ์ธ ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. Driver ๊ตฌํ˜„์ฒด๋Š” ๊ณต์‹ ๋ฒค๋”์‚ฌ(ex Oracle, MS)๊ฐ€ ๊ตฌํ˜„ํ•œ ์ตœ์ ํ™”๋œ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. 

JDBC 4.0 ๋ถ€ํ„ฐ๋Š” ์ง์ ‘ ๋“ฑ๋ก ์•ˆํ•ด๋„, META-INF/services/java.sql.Driver ๊ฒฝ๋กœ์— ๋‘๋ฉด JDBC Driver๊ฐ€ ์‹คํ–‰๋  ๋•Œ ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

 

 

- DataSource

์‹ค์ œ ๊ตฌํ˜„์ฒด์—์„œ DriverManager๋กœ ์ง์ ‘ ์ปค๋„ฅ์…˜์„ ๊ฐ€์ ธ์˜ค๋“ , ์ปค๋„ฅ์…˜ ํ’€์ด๋‚˜ ์ด๋ฏธ ์žˆ๋Š” DataSource๋ฅผ ๋ž˜ํ•‘ํ•ด์„œ ์‚ฌ์šฉํ•˜๋“  ์ถ”์ƒํ™”ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ์— ์•„๋ฌด ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค.

* ๋‹น์—ฐํ•œ๊ฑฐ์ง€๋งŒ DriverManager ๋‚ด๋ถ€ ์ฝ”๋“œ์—๋Š” DataSource ๋Š” ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ปค๋„ฅ์…˜ ํ’€ ๊ฐ์ฒด๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์—†๋Š”๋ฐ, Spring์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด DriverManagerDataSource๋ฅผ ์ด์šฉํ•˜๋ฉด ์†์‰ฝ๊ฒŒ DriverManager ์— ์ปค๋„ฅ์…˜ํ’€์„ ๋ถ™์—ฌ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ž๋ฐ”์—์„œ DataSource ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” JDBC Driver๊ฐ€ ๊ฐ€์ ธ์˜จ DB ์ปค๋„ฅ์…˜๊ณผ ์ปค๋„ฅ์…˜ ํ’€์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. DataSource์˜ ๊ตฌํ˜„์ฒด ๋˜ํ•œ DB ๋ฒค๋”์‚ฌ ๋˜๋Š” ์„œ๋“œํŒŒํ‹ฐ์‚ฌ๋ฅผ ํ†ตํ•ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„ JDBC DataSource ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ(=์ด๋ฆ„)
Commons DBCP ( * Apache DBCP ) 
https://d2.naver.com/helloworld/5102792
org.apache.commons.dbcp2.BasicDataSource
Tomcat JDBC (* ํ†ฐ์บฃ ๋‚ด์žฅ DBCP) org.apache.tomcat.jdbc.pool.DataSource
DRUID ( * ์•Œ๋ฆฌ๋ฐ”๋ฐ” DBCP ) com.alibaba.druid.pool.DruidDataSource
HikariCP ( * Spring ๊ธฐ๋ณธ DBCP ) com.zaxxer.hikari.HikariDataSource

 

 

 

๐Ÿ€ Connection Timeout์€ ์™œ ๋ฐœ์ƒํ•˜๋Š”๊ฑธ๊นŒ์š”?

JDBC Driver๋„ ๊ฒฐ๊ตญ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด DB ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ์ž…๋‹ˆ๋‹ค. ๋ณดํ†ต ์†Œ์ผ“์„ ์ด์šฉํ•œ TCP/IP ์—ฐ๊ฒฐ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—  ์ฝ๊ธฐ ๋„์ค‘ Connection Timeout, Socket Timeout์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. DB ๊ตฌํ˜„์ฒด๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒ ์ง€๋งŒ ๋ณดํ†ต ์ปค๋„ฅ์…˜์ด ๋Š์–ด์ง„ ๊ฒฝ์šฐ ์‹คํ–‰์ค‘์ธ ์ฟผ๋ฆฌ๊ฐ€ ์ทจ์†Œ๋˜๊ณ  ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ๋ฉ๋‹ˆ๋‹ค.

 

- Connection Timeout : ์ตœ์ดˆ ์—ฐ๊ฒฐ์„ ๋งบ๋Š” ์‹œ๊ฐ„(์ž„๊ณ„์น˜, threshold)๋ฅผ ์ดˆ๊ณผ๋œ ๊ฒฝ์šฐ

- Socket Timeout : ์—ฐ๊ฒฐ์€ ์„ฑ๊ณตํ–ˆ์œผ๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ๋•Œ ๊ฐœ๋ณ„ ํŒจํ‚ท ์‘๋‹ต์‹œ๊ฐ„์„ ์ดˆ๊ณผํ•œ ๊ฒฝ์šฐ

์ด๋ฏธ์ง€ ์ถœ์ฒ˜ https://netmarble.engineering/jdbc-timeout-for-game-server

 

 

์—ฌ๊ธฐ์— ์ถ”๊ฐ€๋กœ JDBC Driver์—์„œ Statement Timeout ๊นŒ์ง€ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. 

SocketTime์ด ๋ฌผ๋ฆฌ์ ์ธ ์—ฐ๊ฒฐ์—์„œ ๋„คํŠธ์›Œํฌ ์žฅ์• ๋ฅผ ์˜๋ฏธํ•œ๋‹ค๋ฉด, Statement Timeout์€ DB์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ํ•˜๋‚˜์˜ SQL Statement ์ˆ˜ํ–‰์‹œ๊ฐ„์— ๋Œ€ํ•œ ํƒ€์ž„ ์•„์›ƒ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋‹ด์œผ๋กœ Spring TransactionManager๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํŠธ๋žœ์žญ์…˜ timeout ๋„ ์ถ”๊ฐ€๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ SQL ์‹คํ–‰์‹œ๊ฐ„์— ์ œํ•œ์„ ๊ฑธ๊ธฐ์œ„ํ•ด Statement Timeout์„ ์„ค์ •ํ•  ๊ฒฝ์šฐ, ๋‹น์—ฐํžˆ Socket Timeout ์„ ๋” ํฌ๊ฒŒ ์žก์•„์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค. ์–ด์ฐจํ”ผ ์†Œ์ผ“์ด ๋Š๊ธฐ๋ฉด ๋‚ด๋ถ€์—์„œ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ–ˆ๋˜ ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜์€ ๋กค๋ฐฑ๋˜๋‹ˆ๊นŒ์š”. 

 

Connection -> Statement (StatementTimeout ๋ฐœ์ƒ์ง€์ ) -> ์‹ค์ œ ์ปค๋„ฅ์…˜ (TCP, SocketTimeOut ๋ฐœ์ƒ์ง€์ )

 

 

 

 

 

 

๐Ÿ€ DB Connection Pool (DBCP) ๋Š” ์™œ ์‚ฌ์šฉํ•˜๋‚˜์š”?

๋ฏธ๋ฆฌ ์ปค๋„ฅ์…˜(TCP ์—ฐ๊ฒฐ)์„ ๋‹ค ํ•ด๋†“๊ณ  Connection ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์‹œ์ ์— DB HealthCheck ๋งŒ ํ•œ๋ฒˆ ํ•ด๋ณด๊ณ  ์žฌ์‚ฌ์šฉ ํ•˜๋Š” ๋ฐฉ์‹

DB ์ปค๋„ฅ์…˜์„ ์–ป๋Š” ๊ณผ์ •
1. [์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„]๋Š” JDBC ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•ด ์‹ค์ œ DB ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปค๋„ฅ์…˜์„ ์กฐํšŒํ•œ๋‹ค.
2. ์š”์ฒญ ๋ฐ›์€ DB ๋“œ๋ผ์ด๋ฒ„๋Š” TCP/IP ์ปค๋„ฅ์…˜์„ ์—ฐ๊ฒฐํ•œ๋‹ค. (TCP 3 Way-Handshake)
3. ์—ฐ๊ฒฐ๋œ ์ปค๋„ฅ์…˜์œผ๋กœ [DB ์„œ๋ฒ„]์— ๋กœ๊ทธ์ธ ์š”์ฒญ ๋ฐ ์„ธ์…˜ ๋ถ€๊ฐ€์ •๋ณด๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
4. ์š”์ฒญ๋ฐ›์€ [DB ์„œ๋ฒ„]๋Š” ์ธ์ฆ์„ ์™„๋ฃŒํ•˜๊ณ  [์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„]์™€ ํ†ต์‹ ํ•  DB ์„ธ์…˜์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค.
5. [DB ์„œ๋ฒ„]๋Š” ์ปค๋„ฅ์…˜ ์ƒ์„ฑ์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋Š” ์‘๋‹ต์„ ๋ณด๋‚ธ๋‹ค.
6. DB ๋“œ๋ผ์ด๋ฒ„๋Š” ์—ฐ๊ฒฐ์ด ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆํ•œ ํ›„, ์ƒˆ๋กœ์šด Connection ๊ฐ์ฒด๋ฅผ [์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„]์— ์ „๋‹ฌํ•œ๋‹ค.   

 

DB Connection Pool (์ดํ•˜ DBCP) ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ณผ์ •์€ ๋น„์šฉ๋„ ๋งŽ์ด ๋“ค๊ณ  ๊ทธ ๊ณผ์ • ์ž์ฒด๋„ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.  ๊ทธ๋ž˜์„œ ๋งค๋ฒˆ ์ƒˆ๋กญ๊ฒŒ ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ  ์ปค๋„ฅ์…˜ ํ’€(= ์ปค๋„ฅ์…˜ ์ €์žฅ์†Œ)๋ฅผ ์ด์šฉํ•ด ๋ฏธ๋ฆฌ ์ปค๋„ฅ์…˜์„ ๋งŒ๋“ค์–ด๋‘๊ณ  ์žฌ์‚ฌ์šฉํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์—… Map์„ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค๋งŒ ๋ณดํ†ต์€ ์ž˜ ๋งŒ๋“ค์–ด์ง„ ์ปค๋„ฅ์…˜ํ’€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. ์Šคํ”„๋ง์€ ๊ธฐ๋ณธ์œผ๋กœ HikariCP ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋ฒค์น˜๋งˆํฌ ๋งํฌ๋ฅผ ๋ณด๋ฉด ์–ด๋–ค ์ ์ด ์ข‹์•„์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ฑ„ํƒ๋˜์—ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฏธ๋ฆฌ ์ปค๋„ฅ์…˜(TCP ์—ฐ๊ฒฐ)์„ ๋‹ค ํ•ด๋†“๊ณ  Connection ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์‹œ์ ์— DB HealthCheck ๋งŒ ํ•œ๋ฒˆ ํ•ด๋ณด๊ณ  ์žฌ์‚ฌ์šฉ ํ•˜๋Š” ๋ฐฉ์‹

 

Java ์ปค๋„ฅ์…˜ ํ’€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฒฝ์šฐ ๋Œ€๋ถ€๋ถ„ ๋ฒค๋”์‚ฌ์˜ DataSource๋ฅผ ๋ž˜ํ•‘ํ•˜์—ฌ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด HikariCP๋ผ๋ฉด HikariDataSource ์— ์‚ฌ์šฉํ•  DB๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋ฐ”๋กœ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๊ฒŒ ๊ตฌ์„ฑํ•ด๋‘ก๋‹ˆ๋‹ค. ์ด๋•Œ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ ๋ณดํ†ต jdbcUrl๋กœ ๋งŽ์ด ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

  • < JDBC URL + DB Driver > ์„ค์ •
    jdbcUrl: jdbc:mysql://localhost:3306/world?serverTimeZone=UTC&CharacterEncoding=UTF-8
  • < DataSource ๊ตฌํ˜„์ฒด >  className ์„ค์ •
    dataSourceClassName: oracle.jdbc.pool.OracleDataSource

 

 

 

- DataSource ๊ตฌํ˜„์ฒด ์„ค์ • (DataSource-ClassName ์„ค์ •)

DataSource ๊ตฌํ˜„์ฒด๋ฅผ ์ง์ ‘ ๋ช…์‹œํ•˜์—ฌ ์ปค๋„ฅ์…˜ ํ’€์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • DataSource ๊ตฌํ˜„์ฒด๋งŒ ์žˆ๋Š” ์„ค์ •์„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

DataSource ์ด๋ฆ„์€ ์—ฌ๊ธฐ์—์„œ ํ™•์ธ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. https://github.com/brettwooldridge/HikariCP#popular-datasource-class-names

// DataSourceClassName ์„ค์ •์€ com.zaxxer.hikari.util.DriverDataSource ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
HikariConfig config = new HikariConfig();

// PostgreSQL์˜ DataSource ๊ตฌํ˜„์ฒด ํด๋ž˜์Šค ์ด๋ฆ„์„ ์„ค์ •
config.setDataSourceClassName("org.postgresql.ds.PGSimpleDataSource");
config.addDataSourceProperty("user", "user");
config.addDataSourceProperty("password", "password");
HikariDataSource dataSource = new HikariDataSource(config);

 

 

 

 

- ์ž๋ฐ” ํ‘œ์ค€ JDBC URL + DB Driver (driver-class-name)

ํ‘œ์ค€ jdbcUrl์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ด์„œ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ง๊ด€์ ์ด๊ณ  ํŽธํ•ด์„œ ๋งŽ์ด ์‚ฌ์šฉํ•˜์ง€๋งŒ ํŠน์ • DB์—๋งŒ ์žˆ๋Š” ์„ค์ •์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. 

HikariConfig config = new HikariConfig();

// PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ JDBC URL ์„ค์ •
String jdbcUrl = "jdbc:postgresql://localhost:5432/mydatabase";
config.setJdbcUrl(jdbcUrl);
HikariDataSource dataSource = new HikariDataSource(config);

 

์ฝ”๋“œ๋กœ ๋ณด๋ฉด ์–ด์ƒ‰ํ• ์ˆ˜๋„ ์žˆ๋Š”๋ฐ ์Šคํ”„๋ง๋ถ€ํŠธ์˜ ์ž๋™๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด yml๋กœ ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€๋” DB ์ž์ฒด ์„ค์ •์œผ๋กœ ์ฐฉ๊ฐํ•˜์‹œ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๋Š” HikariDataSource์—์„œ ํ•˜๋Š” ์„œ๋ฒ„ ํƒ€์ž„์•„์›ƒ ๊ฐ’ & ์ปค๋„ฅ์…˜ ํ’€ ์„ค์ •์ž…๋‹ˆ๋‹ค.

spring:
 datasource:
   # ex) spring.datasource.driver-class-name → HikariConfig.setDriverClassName()
   driver-class-name: com.mysql.cj.jdbc.Driver
   url: jdbc:mysql://localhost:3306/world?serverTimeZone=UTC&CharacterEncoding=UTF-8
   username: root
   password: your_password
   hikari:
      # ์Šค๋ ˆ๋“œ๊ฐ€ HikariCP์— connection์„ ์š”์ฒญํ•˜๊ณ , ์ด๋ฅผ ๋Œ€๊ธฐํ•˜๋Š” ์ตœ๋Œ€์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. * DB timeout ์•„๋‹™๋‹ˆ๋‹ค.
      connection-timeout: 3000
      # HikariCP ์ปค๋„ฅ์…˜ ํ’€์˜ ์ด๋ฆ„.
      pool-name: HikariCP-Writer
      # ๊ธฐ๋ณธ์œผ๋กœ ์„ค์ •ํ•  autoCommit ๊ฐ’. ๋ณดํ†ต read-only๋Š” true ๋กœ, writer๋Š” false๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
      auto-commit: false
      
      # JDBC 4.0 ์ด์ „์—๋Š” ๊ฐ DB๊ฐ€ Connection.isValid() ๊ฐ™์€ ๊ฑธ ์ง€์›ํ•˜์ง€ ์•Š์•„์„œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ–ˆ๋‹ค.
      # ๋ฌผ๋ก  ์ง€๊ธˆ์€ ์ „~ํ˜€ ํ•„์š” ์—†๋Š” ๊ธฐ๋Šฅ
      connection-init-sql: SET TIME ZONE 'UTC' # ์ปค๋„ฅ์…˜ ์ƒ์„ฑํ•  ๋•Œ ๋งˆ๋‹ค ์ฟผ๋ฆฌ
      connection-test-query: SELECT 1 # ์ƒˆ๋กœ์šด ์ปค๋„ฅ์…˜์„ ์ฃผ๊ธฐ ์ „ DB ํ—ฌ์Šค์ฒดํฌ ํ•˜๋Š” ์ฟผ๋ฆฌ
      
      # ์ƒˆ๋กœ์šด ์ปค๋„ฅ์…˜์„ ์ฃผ๊ธฐ ์ „ DB ํ—ฌ์Šค์ฒดํฌ timeout ์‹œ๊ฐ„, ์ฐธ๊ณ ๋กœ connection-init-sql์—๋„ ๊ฐ™์ด ์ ์šฉ๋จ
      validation-timeout: 2000
      
      # ํ’€์—์„œ ์œ ์ง€๋˜๋Š” ์ตœ์†Œํ•œ์˜ ์œ ํœด ์ปค๋„ฅ์…˜ ์ˆ˜.
      minimum-idle: 10
      # ํ’€์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์ปค๋„ฅ์…˜ ์ˆ˜.
      maximum-pool-size: 50
      # ์ปค๋„ฅ์…˜์ด ์œ ํœด ์ƒํƒœ๋กœ ์žˆ์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ), DB ์ž์ฒด ์ปค๋„ฅ์…˜ ์ˆ˜๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค๋ฉด ์‹œ๊ฐ„์„ ์ค„์—ฌ์•ผํ•จ
      idle-timeout: 30000
      # ํ’€์— ์ปค๋„ฅ์…˜์ด ์ƒ์„ฑ๋œ ํ›„ ์žˆ์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€์‹œ๊ฐ„ (๋ฐ€๋ฆฌ์ดˆ), DB ์ž์ฒด ์ปค๋„ฅ์…˜ ์ˆ˜๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค๋ฉด ์‹œ๊ฐ„์„ ์ค„์—ฌ์•ผํ•จ
      max-lifetime: 50000

 

์ฐธ๊ณ ๋กœ reader, writer๋ฅผ ๋”ฐ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด @ConfigurationProperties๋ฅผ ํ™œ์šฉํ•ด ๊ฐ๊ฐ ๋”ฐ๋กœ ์„ค์ •ํ•ด์ฃผ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

 

 

๐Ÿ€ ์ปค๋„ฅ์…˜ ํ’€(HikariCP) ์€ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ•˜๋Š”๊ฒŒ ์ข‹์„๊นŒ์š”?

HikariCP ๊ธฐ์ค€์œผ๋กœ ์„ค๋ช…ํ•˜๋ฉด ์ถ”์ฒœ๊ฐ’์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

HikariCP ์„ค์ • ์„ค๋ช… ์ถ”์ฒœ๊ฐ’
maximum-pool-size ์ปค๋„ฅ์…˜ ํ’€์˜ ์ตœ๋Œ€ ํฌ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10๊ฐœ) ์ถ”์ฒœ๊ฐ’ 50 ๊ฐœ
์ƒํ™ฉ์— ๋”ฐ๋ผ ์กฐ์ ˆํ•ด์•ผํ•œ๋‹ค.
minimum-idle ์ปค๋„ฅ์…˜ ํ’€์˜ ์ตœ์†Œ ํฌ๊ธฐ
์ •ํ™•ํžˆ๋Š” ํ’€์—์„œ ์œ ์ง€๋  ์ตœ์†Œ ์œ ํ›„(Idle) ๊ฐœ์ˆ˜
(๊ธฐ๋ณธ๊ฐ’ 10๊ฐœ) ์„ค์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  โœ… ์‘๋‹ต์†๋„๊ฐ€ ์ค‘์š”ํ•œ ์‹œ์Šคํ…œ์ด๋ผ๋ฉด max ์™€ min ์„ ๋™์ผํ•˜๊ฒŒ ๋งž์ถฐ ํ•ญ์ƒ ์ปค๋„ฅ์…˜์ด ์‚ด์•„์žˆ๋„๋ก ์œ ์ง€ํ•œ๋‹ค.

โœ… pool size์˜ ๊ฒฝ์šฐ ์„œ๋ฒ„์˜ ์ตœ๋Œ€ ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์ง€์ •ํ•ด์•ผํ•œ๋‹ค. ์ปค๋„ฅ์…˜ ๋˜ํ•œ Pool Locking ์ƒํƒœ๊ฐ€ ๋˜์–ด ๋ฐ๋“œ๋ฝ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. *๊ธ€ ํ•˜๋‹จ์— ์ถ”๊ฐ€ ์„ค๋ช…์žˆ์Œ
connection-timeout HikariCP ์ปค๋„ฅ์…˜ ์š”์ฒญ ํ›„ ๋Œ€๊ธฐํ•˜๋Š” ์‹œ๊ฐ„ (DB ์„ค์ •๊ณผ๋Š” ๊ด€๋ จ ์—†๋‹ค)

์ฆ‰, ์ด๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ๋Œ€๊ธฐ์‹œ๊ฐ„์„ ํฌํ•จํ•˜๊ธฐ์— statement-timeout ๊ณผ validation-timeout์„ ๊ณ ๋ คํ•ด์„œ ์ง€์ •ํ•ด์•ผํ•œ๋‹ค.
(๊ธฐ๋ณธ๊ฐ’ 30์ดˆ) ์ถ”์ฒœ๊ฐ’ 3,000ms
max-lifetime ์ปค๋„ฅ์…˜ ํ’€์—์„œ ๋Œ€๊ธฐํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋„ฅ์…˜์˜ ์ตœ๋Œ€ ์ƒ๋ช…์ฃผ๊ธฐ(์‹œ๊ฐ„)
(๊ธฐ๋ณธ๊ฐ’ 30๋ถ„) ์ถ”์ฒœ๊ฐ’ 50,000ms

DB์˜ wait_timeout (idle_transaction_session_timeout) ๋ณด๋‹ค ๋ฐ˜๋“œ์‹œ ์ž‘๊ฒŒ ์„ค์ •ํ•ด์•ผ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค.
idle-timeout ๋†€๊ณ ์žˆ๋Š” (idle) ์ปค๋„ฅ์…˜์ด ์ž๋™ Close ๋˜๊ธฐ ์ „ ๋Œ€๊ธฐ์‹œ๊ฐ„ ์ถ”์ฒœ๊ฐ’ 50,000ms
pool size ๋ฅผ ๊ณ ์ •ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด 0 (๋ฌดํ•œ)์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.
  โœ… max-lifetime ๊ณผ idle-timeout์„ ๋„˜๊ธฐ๋”๋ผ๋„ minimum-idle ๋ฅผ ์ดˆ๊ณผํ•œ ๊ฒฝ์šฐ๋งŒ ์ปค๋„ฅ์…˜์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

โœ… idle-timeout์€ max-lifetime๋ณด๋‹ค ์ž‘์€ ๊ฐ’์ด์–ด์•ผ ์˜๋ฏธ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด idle ์ƒํƒœ๊ฐ€ ๋˜๊ธฐ ์ „ ์ปค๋„ฅ์…˜์ด ์‚ญ์ œ๋˜์—ˆ๋‹ค๊ฐ€ ์ƒˆ๋กœ ์ƒ์„ฑ๋ ํ…Œ๋‹ˆ๊นŒ์š”.

keepalive-time DB ๊ฐ€ ์ปค๋„ฅ์…˜์„ ์ž์ฒด์ ์œผ๋กœ ๋Š์ง€ ์•Š๋„๋ก HikariCP๊ฐ€ DB ํ—ฌ์Šค์ฒดํฌ Connection.isValid() ๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๋Š” ์ตœ๋Œ€์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ 30,000ms ๋ณด๋‹ค ์ž‘๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์—†๊ฒŒ ๋ง‰ํ˜€์žˆ์Šต๋‹ˆ๋‹ค.
(๊ธฐ๋ณธ๊ฐ’ 60000ms) ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ
์‘๋‹ต ์†๋„๊ฐ€ ์ค‘์š”ํ•˜๋‹ค๋ฉด 30,000ms
validation-timeout  HikariCP ์—์„œ ์ปค๋„ฅ์…˜์„ ์ฃผ๊ธฐ ์ „ DB ํ—ฌ์Šค์ฒดํฌ ์˜ ํƒ€์ž„์•„์›ƒ, Connection.isValid() 
์ถ”์ฒœ๊ฐ’ 1000ms ์ดํ•˜
  โœ… DB ํ—ฌ์Šค์ฒดํฌ ์šฉ๋„์ธ Connection.isValid() ๋Š” JDBC4.0 ๋ถ€ํ„ฐ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ, ๊ทธ ์ด์ „์—๋Š” connection-init-sql ๊ฐ™์€ ๊ฑธ๋กœ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ๊ตฌ์‹œ๋Œ€ ์œ ๋ฌผ์ด๋ผ ์‚ฌ์šฉํ•  ์ผ์ด ์—†๋‹ค. ์ฐธ๊ณ ๋กœ connection-init-sql์—๋„ validation-timeout์ด ๋™์ผํ•˜๊ฒŒ ๊ฑธ๋ฆฐ๋‹ค.
autoCommit ์œ„์—์„œ๋„ ์„ค๋ช…ํ•œ auto-commit์˜ ๊ธฐ๋ณธ๊ฐ’ Writer ์ž‘์—…์ด ๋งŽ์€๊ฒฝ์šฐ true
Read ์ž‘์—…์ด ๋งŽ์€ ๊ฒฝ์šฐ false
     

 

 

DB ์™€ TCP ํ†ต์‹  ์ค‘ ๋ฐœ์ƒํ•˜๋Š” Connection Timeout ์ด๋‚˜ Socket Timeout (==Read Timeout) ์€ ์ปค๋„ฅ์…˜ ํ’€๊ณผ๋Š” ๊ด€๋ จ ์—†์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•˜๋‹ค๋ฉด ์ด๋Š” JDBC URL๋กœ ์ง์ ‘ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •, ํŠน์ • ์ฟผ๋ฆฌ๋งŒ ์„ค์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด java.sql.Statement.setQueryTimeout(int timeout) ์‚ฌ์šฉ
spring:
  datasource:
    url: jdbc:mysql://hostname:3306/database?socketTimeout=10000&connectTimeout=10000

HikariCP์˜ connection-timeout ๊ณผ JDBC Url์— ๊ฑฐ๋Š” TCP ํ†ต์‹  ์ž์ฒด์˜ connection-timeout์€ ์™„์ „ ๋‹ค๋ฅธ ์„ค์ •์ž„์„ ์œ ์˜ํ•˜์ž.

 

 

JDBC์—์„œ ๋”ฐ๋กœ ์ œ๊ณตํ•˜๋Š” Statement Timeout์€ Statement.setQueryTimeout() ๋ฉ”์„œ๋“œ๋กœ ์ง์ ‘ ๊ฑธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๋˜ํ•œ Spring @Transaction(timeout=...)์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•˜๋Š” Transaction Timeout๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

๐Ÿ€ Connection Pool ๊ณผ ์Šค๋ ˆ๋“œ์˜ ์ƒ๊ด€๊ด€๊ณ„ ( HikariCP ๋ฐ๋“œ๋ฝ )

connection pool size์˜ ๊ฒฝ์šฐ ์„œ๋ฒ„์˜ ์ตœ๋Œ€ ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์ง€์ •ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด Pool Locking ์œผ๋กœ HikariCP ์ž์ฒด ๋ฐ๋“œ๋ฝ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„ ์ด๋Š” ์ž˜ ์•Œ๋ ค์ง„ ์ด์Šˆ๋ผ์„œ ์•„๋ž˜ ๊ณต์‹์— ๋”ฐ๋ผ ๊ฐœ์ˆ˜๋ฅผ ์ง€์ •ํ•ด์ฃผ๋ฉด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

Pool Locking์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1. ํ˜„์žฌ ํ•œ ํŠธ๋žœ์žญ์…˜ (ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ)์—์„œ ์ปค๋„ฅ์…˜์„ ๋ฌผ๊ณ  ์žˆ๋Š” ์ƒํƒœ๋กœ, ์ปค๋„ฅ์…˜์„ ํ•˜๋‚˜ ๋” ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•จ
- ์˜ˆ๋ฅผ ๋“ค์–ด insert ํ•  ๋•Œ id_auto_increment๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์„œ๋ธŒ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ID ๋ฐ›์•„์˜ค๋Š” ์ปค๋„ฅ์…˜ ์ถ”๊ฐ€ ์ƒ์„ฑ
2. ๊ทธ๋Ÿฐ๋ฐ ์„œ๋ฒ„๋ฅผ ๋นก์„ธ๊ฒŒ ๋Œ๋ ค์„œ ํ’€์— ๋‚จ์•„ ์žˆ๋Š” ์ปค๋„ฅ์…˜์ด ์—†์Œ.
3. ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ์ปค๋„ฅ์…˜์„ 1๊ฐœ์”ฉ ๋“ค๊ณ  ์„œ๋กœ๊ฐ€ ์„œ๋กœ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ฐ๋“œ๋ฝ ์™„์„ฑ ^ใ…^
4. ์ด์ œ ์ปค๋„ฅ์…˜์„ ์–ป์ง€ ๋ชปํ•ด์„œ, HikariCP ๊ธฐ๋ณธ timeout์ธ 30์ดˆ๋ฅผ ๋„˜๊ฒจ ๋Œ€๋ถ€๋ถ„์˜ ์š”์ฒญ์ด rollback -> ๋Œ€ ์žฅ์• !

 

ํ•ด๋‹น ํ˜„์ƒ์— ๋Œ€ํ•ด์„œ๋Š” (2020 ๋ฐฐ๋‹ฌ์˜๋ฏผ์กฑ) HikariCP Dead lock์—์„œ ๋ฒ—์–ด๋‚˜๊ธฐ (์ด๋ก ํŽธ) ๊ธ€์—์„œ๋„ ์ž์„ธํ•˜๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

๐Ÿ“š ๋ ˆํผ๋Ÿฐ์Šค

(2022 ๋„ท๋งˆ๋ธ” ์—”์ง€๋‹ˆ์–ด๋ง) ๊ฒŒ์ž„ ์„œ๋ฒ„ ์‹œ์Šคํ…œ์„ ์œ„ํ•œ JDBC์™€ Timeout ์ดํ•ดํ•˜๊ธฐ
(2022 ๋„ท๋งˆ๋ธ” ์—”์ง€๋‹ˆ์–ด๋ง) ๊ฒŒ์ž„ ์„œ๋ฒ„ ์‹œ์Šคํ…œ์„ ์œ„ํ•œ HikariCP ์˜ต์…˜ ๋ฐ ๊ถŒ์žฅ ์„ค์ •

 

๊ฒŒ์ž„ ์„œ๋ฒ„ ์‹œ์Šคํ…œ์„ ์œ„ํ•œ HikariCP ์˜ต์…˜ ๋ฐ ๊ถŒ์žฅ ์„ค์ • - ๋„ท๋งˆ๋ธ” ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ

HikariCP๋Š” ํŠน๋ณ„ํžˆ ์˜ต์…˜์„ ํŠœ๋‹ํ•˜์ง€ ์•Š๋”๋ผ๋„ ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ ๋ฐ ๋ฐฐํฌ์—์„œ ์ถฉ๋ถ„ํ•œ ์„ฑ๋Šฅ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฒŒ์ž„ ์„œ๋ฒ„ ์‹œ์Šคํ…œ์„ ์œ„ํ•œ JDBC์™€ Timeout ์ดํ•ดํ•˜๊ธฐ์—์„œ ์ด์•ผ๊ธฐํ•œ ๊ฒƒ์ฒ˜๋Ÿผ WAS ์‹œ์Šคํ…œ์„

netmarble.engineering

 

(2020 ๋ฐฐ๋‹ฌ์˜๋ฏผ์กฑ) HikariCP Dead lock์—์„œ ๋ฒ—์–ด๋‚˜๊ธฐ (์ด๋ก ํŽธ)

(2020 ๋ฐฐ๋‹ฌ์˜๋ฏผ์กฑ) HikariCP Dead lock์—์„œ ๋ฒ—์–ด๋‚˜๊ธฐ (์‹ค์ „ํŽธ)

(2015 ๋„ค์ด๋ฒ„ D2) Commons DBCP ์ดํ•ดํ•˜๊ธฐ

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ