전체 글
-
스프링 트랜잭션 전파Spring/Spring Boot 2021. 11. 9. 23:59
트랜잭션이 이미 진행중인데, 여기에 추가로 트랜잭션을 수행하면 어떻게 될까? 기존 트랜잭션과 별도의 트랜잭션을 진행해야 할까? 아니면 기존 트랜잭션을 그대로 이어 받아서 트랜잭션을 수행해야 할까? 이런 경우 어떻게 동작할지 결정하는 것을 트랜잭션 전파(propagation)라 한다. 참고로 스프링은 다양한 트랜잭션 전파 옵션을 제공한다. 1. 외부 트랜잭션이 수행중인데, 내부 트랜잭션이 추가로 수행됨 - 기본 전파 옵션인 REQUIRED 기준 스프링에서는 이 경우 외부 트랜잭션과 내부 트랜잭션을 묶어서 하나의 트랜잭션을 만들어준다. 내부 트랜잭션이 외부 트랜잭션에 참여하는 것이며 이것이 기본 동작이고 옵션을 통해 다른 동작방식도 선택할 수 있다. 스프링은 논리 트랜잭션과 물리 트랜잭션이라는 개념을 나눈다..
-
동시성 안전한 Set 사용하기: HashSet vs. ConcurrentHashMap.newKeySet카테고리 없음 2021. 11. 7. 13:32
웹 애플리케이션 띄워 특정 키워드를 받아야 하는 상황이라면 메모리에 띄워서 받아오는 것을 택할 수 있다. 이때 단순한 HashSet을 써도 되는지 혹은 특정 시점에서 synchornized 처리를 따로 해야되는지 의문일때가 있다. HashSet을 쓴다면 동시성면에서 안전하지 않다.프로젝트를 진행하며 특히 Spring WebFlux와 같이 비동기 및 논블로킹 환경에서 동시성 안전한 Set을 사용하는 방법은 매우 중요하다. 이번 글에서는 HashSet 대신 동시성에서 안전한 Collections.synchronizedSet와 ConcurrentHashMap.newKeySet를 비교하여 어떤 상황에서 어떤 방법이 더 효율적인지 알아보자.1. HashSet에서 동기화 사용하기 (Collections.sync..
-
스프링 @Transaction 이해Spring/Spring Boot 2021. 10. 29. 12:10
스프링의 트랜잭션 우리는 선언적 트랜잭션 관리를 주로 사용하는데 @Transactional` 애노테이션 하나만 선언해서 매우 편리하게 트랜잭션을 적용하는 것을 선언적 트랜잭션 관리라 하며 스프링 부트로 개발한다면 주로 이 어노테이션 방법으로 개발하게 된다. @Transaction 애노테이션을 선언한다면 스프링의 트랜잭션 AOP는 이 애노테이션을 인식해서 트랜잭션을 처리하는 프록시를 적용해준다. 구체적으로 @Transactional`애노테이션이 특정 클래스나 메서드에 하나라도 있으면 트랜잭션 AOP는 cglib 기반의 프록시 클래스를 만들어서 스프링 컨테이너에 등록한다. 따라서 실제 객체 대신에 프록시인 {클래스}$$CGLIB 을 스프링 빈으로 등록한다. 그리고 프록시는 내부에 실제 객체를 참조하게 된다...
-
clusterRole, clusterRoleBindingDevOps/Kubernetes 2021. 10. 29. 08:59
롤과 롤바인딩은 네임스페이스가 지정된 리소스로, 하나의 네임스페이스상에 상주하며 해당 네임스페이스의 리소스에 적용된다는 것을 의미한다. 일반 롤은 롤이 위치하고 있는 동일한 네임스페이스의 리소스에만 액세스할 수 있다. 다른 네임스페이스의 리소스에 누군가가 액세스 할 수 있게 하려면 해당 네임스페이스마다 롤과 롤바인딩을 만들어야 한다. 클러스터 수준 리소스에 액세스 권한을 부여하려면 클러스터롤바인딩과 클러스터롤을 사용해야 한다. 예를 들어 어떤 리소스들은 전혀 네임스페이스를 지정하지 않는데 노드, 퍼시스턴트 볼륨 등이 있다. 클러스터 롤은 네임스페이스가 지정되지 않은 리소스나 리소스가 아닌 URL에 액세스를 허용하는 클러스터 수준의 리소스로 각 네임스페이스에 동일한 롤을 재정의할 필요 없이 개별 네임스페이..
-
Lettuce와 Jedis: Redis 클라이언트의 비교카테고리 없음 2021. 10. 28. 23:19
Redis는 빠르고 유연한 메모리 기반 데이터 저장소로, 다양한 애플리케이션에서 사용된다. Java 환경에서 Redis와 상호 작용하기 위해 주로 사용되는 클라이언트 라이브러리는 Lettuce와 Jedis이다. 이 글에서는 Lettuce의 주요 특징과 Jedis와의 비교를 통해, 각 라이브러리의 장단점을 살펴보자.Lettuce의 주요 특징Lettuce는 비동기, 동기, 반응형 API를 제공하는 고성능 Redis 클라이언트이다. 내부적으로 non-blocking, 비동기 방식으로 구현되어 있어 높은 성능과 유연성을 제공한다.Non-blocking, 비동기 처리:Lettuce는 Netty를 기반으로 하여 non-blocking 방식으로 작동한다. 이는 높은 동시성 처리를 가능하게 하며, 시스템 리소스를 효율..
-
Reactor List가 비어있을 때의 switchIfEmpty와 defaultIfEmptySpring/Spring 2021. 10. 14. 11:47
Reactor 에서 Mono나 Flux가 비어 있는 경우 대체 값을 제공하는 switchIfEmpty와 defaultIfEmpty 연산자는 매우 유용하다. 이 글에서는 이 두 연산자의 차이점과 사용 예제, 그리고 이를 통해 얻을 수 있는 장점을 살펴보자.switchIfEmpty와 defaultIfEmpty의 차이점switchIfEmptyswitchIfEmpty는 원래 Mono나 Flux가 비어 있을 때 (즉, Mono.empty()나 Flux.empty()인 경우) 대체 Mono나 Flux를 제공하는 연산자이다. 이는 데이터 스트림이 비어 있는 상황에서 다른 데이터 소스로 대체할 때 유용하다.fun getKeywords(info: String, key: String): Mono> { return i..
-
[springboot, kotlin] 배포시 FileReader FileNotFoundExceptionSpring/Spring Boot 2021. 9. 28. 01:17
FileReader("src/main/resources/templates/$fileName.yaml") .readText() 로컬에서는 파일 경로를 읽어와서 잘 읽지만 쿠버네티스 파드에 JAR 패키징으로 실행한 어플리케이션 안에서는 FileNotFoundException이 발견되었다. 실행할 때 jar 로 패키징해서 실행하였다면 InputStream을 써서 읽어야 한다. File로 읽을 수 있는건 자바 메인으로 실행했을 때 파일 경로로 읽을 수 있는것이고 JAR 안에 들이었는 리소스를 클래스패스로 접근해서 읽을 때는 파일시스템에 있는 파일이 아니라 JAR 안에 있는 파일이기 때문이다. javaClass.getResourceAsStream("/data/$fileName") ?.bufferedReader(..
-
충돌이 많을때 왜 낙관적 락을 쓰지 말라고 할까?카테고리 없음 2021. 9. 6. 00:00
데이터베이스나 분산 시스템에서 동시에 여러 트랜잭션이 같은 데이터를 접근할 때 발생할 수 있는 충돌을 관리하기 위해, 동시성을 보장하기 위해 락을 사용한다. 그리고 락을 사용할때 흔히 들은 말은 "충돌이 많으면 비관적 락을 쓰는게 낫다" 이다. 이 같은 말을 들었을때 왜? 라는 의문이 들기보다는 교과서 암기처럼 숙지하고 넘어갔었는데 그 이유에 대해서 알아보려고 한다. 우선 낙관적락과 비관적락이 무엇인지에 대해서 알아보고 어떤 특징이 있는지 확인해보자. Optimistic Locking (낙관적 잠금)Optimistic locking은 트랜잭션이 데이터를 읽을 때는 잠금을 걸지 않고, 데이터를 수정하고자 할 때 다른 트랜잭션이 해당 데이터를 변경했는지 확인하는 방식이다.일반적으로 version numbe..