KATEKEITH / TIL_log

📚 Today I Learned.
0 stars 0 forks source link

Spring Hikari CP VS tomcat-jdbc #10

Open KATEKEITH opened 11 months ago

KATEKEITH commented 11 months ago

Hikari Pool에 커넥션 상태

HikariCP에서 Connection을 할당받는 과정

[Thread-1님] 안녕하세요 Hikari님! Connection 하나만 주세요~

[Hikari님] 안녕하세요 Thread-1님! 저희 pool에서는 Connection을 주는 규칙이 있답니다. 확인해볼게요~

[Hikari님] 이전에 Thread-1님이 저희 pool에 방문한 내역 먼저 살펴볼게요!

[Hikari님] 오! 이전에 방문한 내역이 있으시네요~ 근데 그때 사용한 Connection은 다른 Thread 님이 사용 중(active) 이시네요~ 다른 Thread님이 안 쓰셨으면 빠르게 이 Connection 먼저 드렸을 텐데 아쉽네요ㅠㅠ

[Thread-1님] 괜찮아요! Hikari님 다른 Connection 주세요~

[Hikari님] Pool 전체에서 사용 가능한(idle) Connection이 있는지 찾아볼께요~

[Hikari님] (Loop 돌면서 찾는중…)

[Hikari님] Thread-1님 지금 전체 Connection이 다 사용중이에요! ㅠㅠ 저기 handoffQueue 앞에 가서 좀 기다리셔야 할 것 같아요 ㅜㅜ

[Thread-1님] 네 괜찮아요! (안 괜찮음) 저기서 30초만 기다려보고 없으면 Exception내면 되죠^^ (깨알 Tip. HikariCP default Connection timeout은 30초 입니다.)

[Hikari님] 네 죄송합니다 Thread-1님. 다음에 또 다시 방문해주세요~

[Thread-1님] (handoffQueue에서 다른 Thread가 쓰고 반납한 Connection을 얻었다!)

HikariCP에서 Connection을 반납하는 과정

[Thread-1님] Transaction내의 쿼리를 모두 수행하고 Commit이 되었어 이제 Connection을 반납해볼까?

[Thread-1님] Thread-1님이 (ProxyConnection) connection.close()을 실행하였습니다.

[Hikari님] 안녕하세요 Thread-1님! Connection 이용은 만족스러우셨나요? Connection 반납 절차 도와드리겠습니다.

[Hikari님] 일단 idle Connection으로 바꿀게요 (poolEntry.setState(STATE_NOT_IN_USE))

[Hikari님] handOffQueue에서 Connection을 받길 원하는 다른 Thread님이 있나봐요~

[Hikari님] (handOffQueue에 Connection 삽입)

[Thread-2님] 나이스!! handOffQueue에 Connection 하나 떨어졌다~

[Hikari님] Thread-1님 고생하셨습니다~ 이번에 사용한 Connection 정보 등록해 드릴께요~!
다음에 빠르게 이용하실 수 있으실거에요

[Thread-1님] 감사합니다! Hikari님 또 Connection 받으러 올께요~

repository.save()을 수행하는데 Connection이 몇 개 필요할까요?

(처음엔 1개일거라 생각했지만, getConnection에 대한 디버깅을 해보니 2번의 getConnection 요청이 발생했습니다.)

@Entity
class Message {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;
  private String title;
  private String contents;
}
@Transactional
public Message save(final Message message) {
  return repository.save(message)
}

왜 Connection이 2개나 필요한지 짐작이 되시나요?

범인은 바로 @GeneratedValue(strategy = GenerationType.AUTO)

GenerationType이 AUTO이고, id 변수의 Type이 Long이기 때문에 내부적으로는 SequenceStyleGenerator로 ID를 생성하게 됩니다.

기본적으로 Sequence를 기반으로 ID를 생성하는 Generator이지만 MySQL은 Sequence를 지원하지 않기 때문에 hibernate_sequence라는 테이블에 단일 Row를 사용하여 ID값을 생성합니다.

여기서 hibernate_sequence 테이블을 조회, update를 하면서 Sub Transaction을 생성하여 실행하게 됩니다.

  1. select next_val as id_val from hibernate_sequence for update;
KATEKEITH commented 10 months ago

https://techblog.woowahan.com/2664/ https://techblog.woowahan.com/2663/