spring framework 를 이용하여 트랜잭션을 제어할 일이 생기면 대부분 @Transactional 애노테이션을 이용할 것이다. 이 방식은 가장 간단하기도하며 spring 을 공부하는 자료들에선 대부분 선언적으로 트랜잭션을 다루는 세련된 기법이라고 소개한다. spring 을 공부할때 접하게되는 대표적 키워드들중 AOP 가 있는데, AOP 를 가장 처음으로 접하게 되는 기술이기도하다. 다만 이 방식에는 몇가지 불편한점이 있는데 1. 메서드 레벨에 AOP 가 적용되기 때문에 트랜잭션 단위도 메서드 레벨로 적용(메서드 내에서 지정 불가능) 2. self invocation 에서 트랜잭션 적용 불가 가 대표적이다. 특히 2번은 spring 을 처음 접하는 주니어 개발자라면 이 문제로 인한 삽질을 한번쯤은..
spring batch 에서 JdbcPagingItemReader 를 이용해서 데이터를 조회하는 코드를 작성했다. 이후 배치 잡을 실행했는데 아래와 같은 에러 메세지와 함께 잡이 실패했다. Column 'column4' not found.; nested exception is java.sql.SQLException: Column 'column4' not found. column4 는 임의로 이름을 바꾼거고, 실제로 존재하는 컬럼명을 넣었었다. 혹시 컬럼명에 오타가 있는건가 해서 오타도 확인해보고, 실제로 쿼리를 직접 SQL 에서 실행할때는 잘 돌아가는 것까지 확인했다. JdbcPagingItemReader 를 만드는 코드도 일반적인 관례를 따랐으며, QueryProvider 를 이용했다. SqlPagin..
JPA 에서 엔티티간에 연관관계를 맺을시 연관관계의 주인이 되는 엔티티에는 @JoinColumn 애노테이션을 이용해 FK 를 설정한다. @JoinColumn 에는 여러 프로퍼티들이 있는데 이중 name 에는 해당 엔티티의 컬럼명을, referencedColumnName 에는 상대방 엔티티의 컬럼명을 적는다. referencedColumnName 을 명시적으로 넣어주지 않으면 디폴트 옵션으로 상대방의 primary key 에 해당하는 컬럼을 이용하게된다. @Entity @Table(name = "person") @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Person { @Id @GeneratedVal..
간혹 커뮤니티 등에서 AOP 에 대한 얘기를 하면 많이들 잘 알고있는 내용이 이렇다. "spring 에서는 인터페이스가 있으면 기본적으로 JDK 에서 제공하는 dynamic proxy 를 이용하고, 없으면 CGLIB 를 이용한 상속 기반 프록시를 구현해서 AOP 를 구현한다." 나도 머리로는 잘 이해하고 있긴한데 돌이켜 생각해보면 제가 작성하는 AOP 가 dynamic proxy 로 도는지, CGLIB 로 돌아가는지에 대해 크게 고민해본적이 없다. 그리고 더 곰곰히 생각해보면 dynamic proxy 로 돌아가는 AOP 를 본적이 거의 없다. 그리고 실제로 인터페이스를 구현하게 해서 AOP 를 사용하면 인터페이스가 있음에도 불구하고 CGLIB 로 도는걸 볼 수 있다! (참고로 포스팅 작성 시점 기준 sp..
spring 에서는 멀티스레드 활용을 위해 jdk 에서 제공하는 Executor 인터페이스를 확장한 TaskExecutor 인터페이스를 근간으로 활용하고있다. 아마도 개발자들은 TaskExecutor 구현체로 ThreadPoolTaskExecutor 를 사용하고, spring 에서 제공하는 @Async 애노테이션을 활용한 멀티스레드 프로그래밍을 많이 할 것 같다. 보통 spring-batch 로 spring 을 처음 접하는 경우는 흔치 않을 것이고, spring-mvc 와 같은 web 프로젝트로 spring 에 대해 접한 후 spring-batch 도 접하게 되는 경우가 많을텐데, 이때 기존에 알고있던 spring 의 멀티스레드 프로그래밍 경험으로 코드를 작성하면 job 실행 이후 jvm 이 종료되지 ..
spring batch 에서 chunk oriented 방식을 이용해 로직을 작성하다보면 reader-writer 쌍이 필요해진다. 이때 JPA 를 사용하고 있다면 JpaPagingItemReader 와 JpaItemWriter 를 많이 이용하게 될텐데 이때 writer 에서 저장하는게 신규 엔티티라면 문제가 없지만 기존 엔티티의 업데이트라면 원치않는 select 쿼리가 날아가는걸 경험할 수 있다. public Step chunkStep1() { return stepBuilderFactory.get("chunkStep1") .chunk(500) .reader(chunkReader()) .processor(chunkProcessor()) .writer(chunkWriter()) .build(); } @Be..
spring batch 를 이용하면 JobBuilderFactory, StepBuilderFactory 를 이용해 코드를 작성하게 된다. 이때 factory 가 제공해주는 다양한 속성들이 있는데, 나같은 경우 자동완성으로 뜨긴뜨는데 뭐하는건지 명확히 모르고 그냥 사용하던 것만 사용하고 있었다. 이것들을 한번 정리해본다. preventRestart spring batch 는 job name 과 job parameters 를 이용해 job 인스턴스를 식별한다. job 이 실패했을경우 동일한 식별정보로 job 실행요청이 들어오면 실패한 step 부터 job 을 실행하게되는데 preventRestart 가 설정되어있으면 예외를 일으켜 잡이 다시 실행되는걸 막는다. allowStartIfComplete A job..
이전에 spring cloud config server/client 를 설정하는 포스팅을 올렸었다. ( multifrontgarden.tistory.com/236 multifrontgarden.tistory.com/237 ) server 를 설정하는 부분은 달라진게 없는데 spring boot 2.4 로 올라오면서 client 설정 부분이 좀 달라졌다. 이를 알아보자. 1. spring boot 2.4 방식 사용 먼저 2.4 이전에는 client 에 bootstrap.yml(또는 properties) 파일이 필요했다. 그래서 서버 정보를 입력해두면 라이프사이클 상 application.yml 보다 bootstrap.yml 을 먼저 읽어 config server 에 정의돼있는 프로퍼티들을 읽어보게끔 했었다..
spring boot 2.4 버전부터 애플리케이션 설정 파일( application.properties, application.yml, application.yaml ) 에 대한 구동방식이 변경됐다. 변경된 이유는 k8s 볼륨 마운트 구성때문이라고 하는데 이것에 대해선 논하지 않는다. 설정파일에 대해 어떤것들이 변경됐고, 어떻게 마이그레이션해야하는지 알아보자. # 설정이 단순한 경우 애플리케이션 설정파일을 멀티 모듈로 구성하거나 profile 별로 분리해놓지 않았다면 크게 신경 쓸 필요 없이 그대로 구동하면 된다. # 설정이 분리되어 있는 경우 엔터프라이즈 환경에서 규모있는 애플리케이션을 구성한다면 위처럼 설정 파일이 단일로 있지는 않을 것이다. 멀티모듈로 구성되어있다면 애플리케이션 설정 파일에서 추가적..
# ThreadPoolExecutorjava 에서 멀티스레드 프로그램을 구현시 자바 1.5 에 추가된 concurrent 패키지를 많이 이용하게 된다.concurrent 패키지에 있는 ThreadPoolExecutor 는 Thread 를 직접 생성하고, 관리하는 부분을 추상화하여 작업(task)과 실행(execute)을 분리시켜준다. ThreadPoolExecutor 는 Executors 에 있는 팩토리 메서드를 이용해 간편하게 생성할 수도 있고, 직접 생성자를 호출해서 객체를 생성할 수도 있다.Executors.newCachedThreadPool(); Executors.newFixedThreadPool(10); Executors.newSingleThreadExecutor(); ..
- Total
- Today
- Yesterday
- EffectiveJava
- servlet
- code
- Jackson
- db
- 정규표현식
- Git
- Spring
- programming
- DesignPattern
- JavaScript Core
- OOP
- toby
- frontend개발환경
- generics
- TEST
- MySQL
- go-core
- mariadb
- Design Pattern
- backend개발환경
- java
- spring cloud
- frontcode
- java8
- javascript
- Kotlin
- JPA
- http
- clean code
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
