devlog/TIL

[TIL] ExecutorService / Event Driven Programming / Bulk Insert / DiscriminatorValue / AuditingEntityListener

bandal-gom 2019. 11. 20. 09:07
TIL = Today I Learned | 알게된 내용, 현재로서는 잘 모르겠는 내용을 적는 포스트

Event driven programming - contd

이것에 대해서 잘 모르겠다!
일단은 이 article을 봤음
https://engkimbs.tistory.com/827

ExecutorService (let's deep dive)

코드리뷰를 하다가 이런 클래스를 봤다. threadpool을 정해진 개수만큼 유지하고, concurrent programming 을 할 수 있도록 도와주는 service 인 것 같다.
java.util.concurrent 패키지에 있는 것을 보고 추측함.
newFixedThreadPool
이거는 정해진 thread count 만큼 pool 을 유지하고 (shared unbounded queue => not sure what that means. shared unbounded queue?) 최대로 동시에 동작하는 thread count 를 나타내며, 추가적인 작업이 thread에 요청되면 queue에서 대기를 탐. 실행중인 thread에서 실패가(prior to shutdown) 일어나게 된다면 새로운 thread가 해당 작업의 미처 끝내지 못한 작업을 마무리 함.
thread pool의 thread들은 명시적으로 shutdown 되기 전까지 존재하게 될것임.

근데 여기서 보다가 새로보는 data structure를 보게 됨.

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedBlockingQueue.html
그냥 blocking queue 에 linked node 였다...
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

jooq의 bulk insert 편리성

PR을 보다 보니 이런 멘트를 보게 되었다.


일단 궁금했다. 나는 저런 bulk insert, update를 해본적이 없기 때문.
JPA 에서는 saveAll()를 할때 한번에 쿼리를 날려주는 것 같이 생긴것과는 다르게 한땀 한땀 쿼리를 날려준다.
하지만 상품등록 > 옵션 등록 > 재고 업데이트 까지 한번에 벌크로 처리해야하는 상황에서는 커넥션을 계속 유지하고 있으므로 자원의 낭비가 심하다. 그리고 한 건을 저장하는것이 시간이 오래걸리게 되면 상품등록 bulk라는 요청 자체가 밀리게 되니까 좋지 않다!
하지만 jooq의 values()를 사용하게 되면 한번에 bulk insert (하나의 쿼리!) 가 나가게 되므로 jpa보다는 좋다.

다른방법이 있나 보자. => JdbcTemplate을 사용해서 batchUpdate하는 방법.

Spring Boot Test + Kotlin

JPA DiscriminatorValue

참고: https://docs.oracle.com/javaee/6/tutorial/doc/bnbqn.html
https://stackoverflow.com/questions/16772370/when-to-use-discriminatorvalue-annotation-in-hibernate

@Entity
@Table(name = "mb_member_cs")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "auto_process_yn")
abstract class OrderCs(

root class를 @Inhertance 어노테이션으로 설정해서 entity 매핑을 할 수 있는 방법이다.

public enum InheritanceType {
    SINGLE_TABLE, // 각 hiearchy 마다 한 개의 테이블 매핑 
    JOINED,    // subclass의 필드가 다른 테이블에 매핑 (부모와는 다른필드)되는 방식 
    TABLE_PER_CLASS // 추상 entity class - 테이블 매핑
};

default는 SINGLE_TABLE이다. 대체로 많이 사용되는 방식이라고 한다. @DiscriminatorColumn이 명시되지 않은 경우에는 default 설정인 DTYPE의 이름, STRING 타입 컬럼을 찾는다고 한다.

  • @DiscriminatorColumn
    • SINGLE_TABLE 내에서 abstract class의 subclass들을 구분할 값을 가진 column
  • @DiscriminatorValue
    - @DiscriminatorColumn 에서 명시된 컬럼의 값에 해당하는 entity 위에 해당 annotation을 붙인다. 

다른 타입들은 사용하게 될 때 다시 알아보자.

AuditingEntityListener?

@EntityListeners(AuditingEntityListener.class) 코드에서는 이렇게 쓴다.
이것이 무엇인가. 문서를 보자.
it captures auditing information on persisting and updating entities.
이것도 참고해서 보자 https://www.baeldung.com/database-auditing-jpa

반응형