TransactionSynchronizationManager에 해당하는 글 1

[Spring] JDBC Template 어떻게 Thread-Safe 할까?

JAVA/Spring|2019. 8. 6. 18:27

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 객체 전달 및 전파 필요 없이 트랜잭션 제어를 하기 용이 하다.

 

 

댓글()