[Spring] JDBC Template 어떻게 Thread-Safe 할까?
Spring 스터디중 나온 질문 입니다.
DAO 클래스를 만들때 "JDBC Template"는 new 해서 사용하기도 하지만, "Thread-Safe 하기 때문에 빈으로 등록해서 사용할 수 있다"
Toy 프로젝트 때는 MyBatis를 쓰거나, JPA를 사용하기 때문에 JDBC Template를 사용할 일이 많지 않았지만,
대체 내부 구조가 어떻게 되어있길래 Thread-Safe한거지? 라는 의문이 들었습니다.
(JDBC에 Connection, Statement, ResultSet 은 Thread-Safe 하지 않기 때문에..)
예상 할 수 있는건
락(sync)를 잡아 처리 하나? 아니면 ThreadLocal로 처리하나?
정도로 예상해볼수 있는데 락잡아 처리한다면.. 쫌 아닐꺼라 생각되지만 코드를 살펴봤습니다.
JdbcTemplate의 query, update, execute 등 대부분의 메소드들은 살펴보면 메소드 내에서
DataSourceUtils.getConnection(ds) 를 통해 Connection을 얻어오고 있으며
메소드에서 생성된 ps나 rs 그리고 connection(물론 connection은 무조건 정리하지는 않습니다.) 정리 하고 있습니다.
//즉, JdbcTemplate 객체에 상태 변화 없이 메소드 내에서 모든 리소스가 정리 됨
JdbcTemplate 객체내에서 리소스(예를 들어 Connection)를 정리하지 않고 보존해야 하는경우도 있는데
(예를 들어 @Transaction)
그경우를 위해 DataSourceUtils.getConnection(ds) 코드를 따라가보면
TransactionSynchronizationManager.getResource(ds)를 통해 ConnectionHolder를 가져오는데
TransactionSynchronizationManager.getResource(ds)를 더 들어가보면
ThreadLocal<Map<Object,Object>>로 되어있는 resources를 가져와 ds를 키로 ConnectionHolder를 가져오는것을 볼수 있었습니다.
결론
1. JdbcTemplate 인스턴스는 상태를 갖지 않고 메소드 내에서 생성된 리소스(rs, ps, connection) 들을 정리하기 때문에 Thread-Safe하다
2. Transaction이 필요한경우 정리하면 안되는 Connection의 경우 JdbcTemplate이 상태를 가지지 않고TransactionSynchronizationManager에 ThreadLocal로 보관 하기 때문에 JdbcTemplate를 Thread-Safe하며,
Connection 객체 전달 및 전파 필요 없이 트랜잭션 제어를 하기 용이 하다.
'JAVA > Spring' 카테고리의 다른 글
스프링 부트 2.2 릴리즈노트 (0) | 2019.11.01 |
---|---|
[Spring] zuul 사용시 Eureka client로 분배가 안되는경우 (0) | 2019.08.16 |
[Azure] SpringBoot, AppService로 배포 (0) | 2019.08.02 |
Spring Boot Toy 프로젝트 세션 클러스터링-1 (0) | 2019.07.04 |
Spring Cloud Config Server (0) | 2019.06.25 |