728x90

분류 전체보기 288

[Kotlin] interface default method

코틀린에서는 interface의 default method 를 지원하지 않는다. interface 에 구현부를 포함한 메소들 포함해서 사용할 순 있지만 java의 default method 와는 다르다. 자바 코드로 변환된 내용을 보면 알겠지만 내부클래스를 정의하고 그 안에 static 메소드로 만들어진다. 이로 인해 코틀린 환경에서 JpaRepository 를 상속한 interface 에 구현부를 포함한 메소드를 포함할 경우 컴파일 단계에서 아래와 같은 에러를 마주하게 된다. No property betweenOsVer found for type ${EntityName} spring-data-jpa 에서는 "쿼리 메소드" 라는 기능이 있는데 JpaRepository 를 상속한 interface 해당하는..

Backend/Kotlin 2021.12.22

[JPA] 연관관계 매핑

Entity 연관관계를 매핑할 때 특별한 경우가 아니라면 단방향으로 설계가 권장된다는 말을 많이한다. 그런데 DB 테이블 설계시에는 조인을 고려하고 설계하다보니 기본적으로 양방향이 가능한 구조인데 객체만 단방향으로 설계하기란 쉽지 않다. 예를 들어 게시판을 만든다고 할 때 DB테이블은 게시글을 의미하는 Contents 테이블과 댓글을 의미하는 Reply 테이블을 생성할 것이고 외래키는 N에 해당하는 Reply 에 둘 것이다.(실무에서는 외래키 역할을 하는 칼럼을 추가하긴 하지만 제약조건까지 걸어서 사용하는 경우는 드물다) DB 입장에서 보면 join 을 통해 Contents 를 조회할 때 Reply 정보를 함께 가져올수 있고 Reply 조회시 Contents 정보를 함께 가져올 수도 있다. 어느쪽에서 출..

Backend/JPA 2021.12.17

[JPA] 대량 insert, mysql insert all

jpa 를 사용해서 대량 insert 를 해야할 일이 생겼다. 사실 딱히 대량까진 아니고 많아봐야 1,000건이란 제한이 있는 데이터였다. 그런데 이게 10초가 넘게 걸렸다. jpa에서 대량 insert 시 사용하라고 하는 saveAll 을 사용하는데도 그랬다. mybatis 환경이라면 쿼리로 insert all 를 작성해서 사용했을 것이고 이 경우 insert 하는 데이터가 1만건이 넘어가더라도 10초가 걸리진 않는다. JPA에서 saveAll 로 배치 insert 하려면 application.yml 파일에 아래 설정이 추가로 필요하다. spring.jpa.properties.hibernate.jdbc.batch_size=1000 spring.jpa.properties.hibernate.order_in..

Backend/JPA 2021.12.16

URI, URL

일단 URI가 URL 보다 상위 개념이다. URI 는 특정 http 서버에서 원하는 자원을 얻거나 특정 처리를 위해 서버에 보내는 식별자이고 그 중 URL은 서버에 실제하는 자원의 위치를 정확하게 명시하는 방법이다. 이에 http://localhost:8080/index.html 처럼 특정 자원의 위치를 나타낸다면 URL 이고 http://localhost:8080/user/123 처럼 실제 있는 자원은 아닌데 사전에 협의된 식별자를 호출하는 것이므로 URI 이다. URI는 특정 자원을 직접 호출하는 것이 아니기 때문에 일반적으로 서버에서 요청을 받아서 별도의 추가작업을 수행한다. 간단하게 말해 URL 외에는 모두 URI라고 보면 된다. RestApi Endpoint 는 일반적으로 URI 라고 생각하면 ..

Base/개념정리 2021.12.16

readOnly 구분에 따른 커넥션 선택

jdbc:mysql:replication 스키마도 그렇고 아래에서 설명한 다중DB 커넥션 설정도 그렇고 현재 트랜잭션의 readOnly 값에 따라 master, slave DB가 선택된다. https://findmypiece.tistory.com/255?category=968583 write 작업을 하는 커넥션의 경우 readOnly 값을 기본값인 false 로 지정해서 사용할텐데 대부분 트랜잭션에는 단순히 CUD 쿼리 뿐만 아니라 Read 쿼리도 포함되어 있다. 그렇다면 트래픽을 완전하게 분리하기 위해서 readOnly=false 로 지정된 트랜잭션의 쿼리 중 Read 쿼리는 readOnly=true 로 지정해서 slave DB에서 수행되게 해야 할까? Spring에서 제공하는 트랜잭션 전파 규칙을 이..

Backend/Spring+Boot 2021.12.15

Spring Transaction 전파규칙

Spring에서는 Transaction이 걸려있는 메소드에서 Transaction 걸려있는 또 다른 메소드를 호출할 때 Transaction이 어떻게 전파될 것인지 결정할 수 있다. 다만 이것은 같은 클래스의 메소드끼리는 해당이 없다. 같은 클래스 내의 메소드 호출시에는 Transaction이 걸려있더라도 그냥 최초 호출한 시점에 시작된 Transaction만으로 진행된다. ​ @Transactional 기본속성이다. 기존에 생성된 Transaction이 있으면 참여하고 없다면 새로운 Transaction을 생성한다. 이는 결국 @Transactional(propagation = Propagation.REQUIRED) 를 의미한다. ​ @Transactional(propagation = Propagati..

Backend/Spring+Boot 2021.12.15

HikariCP 커넥션 풀

Spring Boot 2.0을 기점으로 Default DBCP가 Tomcat DBCP -> HikariCP로 바뀌었다. 이는 우리가 흔히 알고 있는 DB커넥션 풀인데 둘이 다른 점이 있어 정리 해놓는다. 일단 Tomcat DBCP 와 달리 HikariCP 는 유휴 커넥션을 유지시키지 않는다. Tomcat DBCP 에서는 test-while-idle 옵션을 통해 유휴커넥션의 세션이 종료되지 않도록 주기적으로 validationQuery 를 날리는 방식을 사용했는데 HikariCP 에서는 maxLifetime이 지나면 해당 커넥션을 폐기하고 다시 생성하는 방식을 사용한다. 이러한 로직은 HikariCP 라이브러리의 HikariPool 내부 클래스인 KeepaliveTask 에서 아래와 같이 확인된다. sof..

Backend/Spring+Boot 2021.12.14

[SpringBoot] JPA+Kotlin 다중 DB 설정

일반적으로 DB서버 master를 하나두고 slave는 여러개를 두고 사용한다. master는 쓰기 작업만 처리하고 slave는 master 에 등록된 데이터가 동기화 되어 읽기 작업만 수행하도록 한다. 가장 간단한 방법은 서버 url 설정시 아래와 같이 jdbc:mysql:replication 스키마를 이용하는 것이다. jdbc:mysql:replication://master,slave1,slave2,slave3/test 이 경우 readOnly=false 일 경우 master로 연결되고 readOnly=true 일 경우 slave1, slave2, slave3 중 랜덤으로 선택되어 연결된다. 하지만 jdbc:mysql:replication 스키마를 사용할 경우 master 서버 커넥션에 문제가 발생할..

Backend/Spring+Boot 2021.12.09

[JPA] EntityManager

JPA가 아닌 환경에서 api호출과 DB수정이 함께 필요한 로직이 있다고 가정해보자. 트랜잭션 단위로 완벽하게 묶을 순 없지만 DB수정 -> api 호출 과 같은 순서로 진행하도록 해 놓으면 api 호출에 문제가 있을 경우 RuntimeException 을 발생시켜서 DB수정을 롤백하면 된다. 하지만 JPA 환경에서는 이게 불가능하다. JPA 는 flush 단계에서 실제 DB로 쿼리를 날리고 flush는 트랜잭션이 종료된 시점에 commit 과 함께 수행되기 때문에 쿼리가 정상인지 여부를 기본적으로 트랜잭션이 종료되는 시점(일반적으로 메소드가 정상 종료된 시점)에 알 수 있다. 이에 트랜잭션으로 묶인 메소드에서 단순히 DB수정 -> api 호출 과 같은 순서로 진행하도록 구성을 해놓을 경우 DB수정 쿼리..

Backend/JPA 2021.12.08

[JPA] SpringBoot JPA 설정

우선 SpringBoot 에서 JPA 설정을 위해 서칭을 하다보면 많은 javaConfig 로 여러 셋팅을 하는 포스팅이 나오지만 그 대부분은 Spring 기준으로 작성된 것이고 SpringBoot 에서는 대부분 자동으로 처리를 해주기 때문에 필요없는 것들이 더 많다. Spring 환경에서는 javaConfig 방식으로 Datasource 빈을 만들어서 이걸 기반으로 EntityManagerFactory 빈을 만들고 또 다시 이걸 기반으로 TransactionManager 빈을 만든다. 추가로 @EnableTransactionManagement 도 추가해서 어노테이션으로 트랜잭션을 관리할 수 있도록 해줘야 한다. 아래 포스팅은 이에 대한 가장 정석적인 내용이다. http://www.devkuma.com/..

Backend/Spring+Boot 2021.12.08
728x90