끄적이는 중...

전체 글 131

[Transactional] Spring이 ThreadLocal을 이용해서 현재 스레드의 DB 자원을 어떻게 연결하는지

Spring은 이런 정보를 관리한다Thread A└─ 현재 트랜잭션 관련 자원 └─ DataSource → ConnectionHolder └─ Connection중요한 건 Connection 자체를 그냥 변수 하나에 박아두는 게 아니라, 보통 DataSource를 키처럼 사용해서 그 DataSource에 연결된 트랜잭션 자원을 찾는 구조다 아래와 같은 관계를 현재 Thread에 묶어 둔다 그래서 나중에 Repository가 DB 작업을 하려고 할 때 지금 이 Thread에서 이 DataSource용 Connection이 이미 있나? 를 확인하고, 있으면 새 Connection을 또 빌리지 않고 기존 Connection을 재사용할 수 있다DataSource A → Conn..

Note
[Transaction] TransactionSynchronizationManager 구조

TransactionSynchronizationManager 란, 현재 Thread에 어떤 트랜잭션 관련 자원이 연결되어 있는지를 관리하는 Spring 클래스Thread A│└─ TransactionSynchronizationManager │ └─ DataSource → Connection #3 왜 DataSource → Connection 형태냐? 여러 DB 자원이 있을 수 있다회원 DB DataSource → Connection #3통계 DB DataSource → Connection #7그래서 그냥 현재 Connection = #3 보다는 이 DataSource에서 사용하는 자원 → 이 Connection 처럼 Key-Value 형태로 찾을 수 있게 관리한다용어DataSource ..

Note
[Transactional] 트랜잭션이 시작됐는데, Connection을 어디다 들고 있지?

TransactionManager가 HikariCP에서 Connection 하나를 가져왔다고 해보자orderRepository.save()를 실행할 때 Connection을 써야 하고 paymentRepository.save() 를 실행할 때도 똑같은 Connection 을 사용해야 같은 DB 트랜잭션에 들어갈 수 있다orderRepository.save(order, connection3);paymentRepository.save(payment, connection3);매번 우리가 위 코드처럼 전달하지 않는다 그런데도 Spring은 어떻게 같은 Connection인지 알까? Spring 공식 문서에서도 일반적인 @Transactional 트랜잭션은 현재 실행 Thread에 트랜잭션을 연결하는 threa..

Note
[Monitoring, Todak-Todag] Application Performance Monitoring

쉽게 말하면 APM(Application Performance Monitoring)은 애플리케이션의 성능과 요청 흐름을 관찰하면서, 어디서 지연이나 오류가 발생했는지 찾기 위한 모니터링 도구 또는 체계라고 보면 된다예를 들어 APM에서는 다음과 같은 정보를 확인할 수 있다요청 응답시간에러율서비스별 지연 시간Trace / Span특정 요청이 어떤 서비스를 거쳤는지어느 구간에서 병목이나 오류가 발생했는지메트릭·로그·Trace를 함께 확인해 원인을 좁히는 과정상용 APM의 예로는 Datadog APM, New Relic 등이 있다 Todak-Todag Troubleshooting다만 Todak-Todag 프로젝트의 문제는 관측 도구가 없는 것이 아니었다 이미 Prometheus·Loki·Zipkin을 통해 메..

Note
[Java] Character

// 검사하기 (true / false)Character.isDigit('5') // true 숫자야?Character.isLetter('a') // true 알파벳이야?Character.isLetterOrDigit('a') // true 알파벳이나 숫자야?Character.isUpperCase('A') // true 대문자야?Character.isLowerCase('a') // true 소문자야?Character.isWhitespace(' ') // true 공백이야?// 바꾸기Character.toUpperCase('a') // 'A' 대문자로Character.toLowerCase('A') // 'a' 소문자..

Note
[Java] StringBuilder

왜 필요하냐면Java의 String은 한 번 만들면 못 고친다 그래서 +로 붙이면 기존 걸 고치는 게 아니라 새 문자열을 통째로 다시 만든다String s = "";s = s + "a"; // "a" 새로 만듦s = s + "b"; // "ab" 새로 만듦 (a를 다시 베껴 씀)s = s + "c"; // "abc" 새로 만듦 (ab를 또 베껴 씀)매번 새 종이에 처음부터 다시 베껴 쓰는 것과 같다 몇 번이면 괜찮지만 10만 번이면 엄청 느려진다StringBuilder는 공책이다 이미 쓴 거 뒤에 이어서 쓰기만 한다사용방식StringBuilder sb = new StringBuilder(); // ① 빈 공책 준비sb.append("a"); // ② 이어 쓰기sb.append("b");..

Note
[Java] == vs equals

String a = "hi";String b = new String("hi"); // 새 컵을 일부러 만듦a.equals(b) // true ← 글자가 같음a == b // false ← 다른 컵비유: 쌍둥이 컵똑같이 생긴 컵이 2개 있다 안에 둘 다 콜라가 들어 있다equals → "안에 든 게 같아?" → 둘 다 콜라니까 true== → "같은 컵이야?" → 생긴 건 같아도 컵이 2개니까 falseString a = "hi";String b = "hi";a == b // true ?!이건 Java가 똑같은 글자를 직접 쓰면 컵 하나를 같이 쓰게 해 줘서 우연히 true가 나온다그래서 "어? 되네?" 하고 쓰다가, 다른 상황에서 갑자기 false가 나와 버그가 생기니 유의할 것..

Note
[Java] switch문의 “→”

코테링크// -> 방식: break 필요 없음case 'w' -> n += 1;// : 방식: break 꼭 필요case 'w': n += 1; break;→를 쓰면 break가 필요 없다→는 그 줄만 실행하고 자동으로 switch를 빠져나온다break가 필요한 건 :를 쓰는 옛날 방식일 때.: 방식에서 break를 빼먹으면, 'w'일 때 아래 's', 'd', 'a' 줄까지 줄줄이 다 실행되어 버린다이 실수를 막으려고 ->가 생긴 것이다

Note