전체 글에 해당하는 글 77

DCL(Double Checked Locking)

JAVA|2020. 9. 8. 19:48
public class DCLInstance {
    private static volatile DCLInstance instance;

    public static DCLInstance getInstance() {
        if (instance == null) {
            synchronized (DCLInstance.class) {
                if (instance == null) {
                    instance = new DCLInstance();
                }
            }
        }
        return instance;
    }
}

 

DCL..

Double Checked Locking..

 

이름을 모르고 락을 잡아 세팅 후 그 이후는 락을 안잡기 위해서 어떻게 해야할까를 고민하다

활용하고 있는 방식인데.. 그게 이름이 있었네요..

그 이름이 DCL 이였습니다

(자바 병렬 프로그래밍에 이 이름이 있었는지는 나중에 다시 읽어봐야겠습니다... 나왔을지도..)

 

뭔가 외우는건 잘 못하지만.. 하나하나 아는것이 실력이니

부족함을 알고 접할때마다 꼼꼼히 이름들을 알고 쓰는걸로..!!

'JAVA' 카테고리의 다른 글

구분자와 문자열 추가 StringJoiner  (0) 2021.08.26
ActiveMQ JDK Version  (0) 2020.09.09
Java Stream  (0) 2020.07.14
Java Time  (0) 2020.07.06
SortedQueue...  (0) 2020.07.02

댓글()

[Spring] SessionStatus는 어떻게 동작할까?

JAVA/Spring|2020. 9. 8. 17:02

Spring MVC 에서 SessionStatus 라는것이 존재합니다.

(현재는 대부분의 서비스회사들이 Session을 사용하지 않기 때문에 사용하지 않는 회사들은 무의미 할수 있겠네요)

 

SessionStatus는 @SessionAttributes를 활용해 Session에 남긴 데이터를 정리하는데 활용을 하는 인터페이스 입니다.

(Controller에 args로 선언해두면 injection이 되며 정리는 setComplete() 를 통해 정리 flag를 세팅합니다.)

 

SessionStatus 에 setComplete()를 호출하게 되면 내부적으로 complete boolean을 세팅하게 되고

RequestMappingHandlerAdapter에서 modelFactory의 updateModel() 내부에서 대상 attribute들을 정리하게 됩니다.

 

여기서 @SessionAttributes이 등장하는데

 

@SessionAttributes는 names를 args로 받게 되고

지정된 names들에 대해서 model에 접근하면 기존 model 저장소가 아닌 Session 영역까지 확장되도록 도움을 줍니다.

 

 

model.addAttribute("dutch", "hello");

 

일반적으로 위 코드 처럼 "dutch" 라는 키로 model에 세팅하면

응답 이후 값이 삭제 됩니다.

 

하지만 컨트롤러 클래스 상단에  @SessionAttribues 를 세팅 후 사용한다면 동작이 변경되게 됩니다.

@RequestMapping("dutch")
@Controller
@SessionAttributes("dutch")
public class DutchController

@SessionAttributes선언 후 model.addAttribute 를 호출한다면 해당 key,value가 Session에 저장 되고,

다음 요청이 동일 세션으로 왔을때 session의 Key를 "dutch"로 조회하면 addAttribute값이 존재하는것을 볼 수 있습니다. 그리고 model을 통해 "dutch"를 조회했을때도 값이 존재하는것을 확인 할 수 있습니다.

 

주의해야할 사항은 해당 컨트롤러가 아닌, 다른 컨트롤러에서 모델에서 "dutch"으로 값을 얻으려 시도하면

값이 들어 있지 않습니다.

위의 컨트롤러의 경우에는 model에 "dutch" 에 해당하는 값을 줘! 라고 하면 @SessionAttributes가 설정되어있는 Key는 Session에서 값을 찾지만

@SessionAttributes("dutch") 가 달려있지 않은 컨트롤러에서 model에 ""dutch" 에 해당하는 값을 줘!" 라고 한다면

Session에서 찾는게 아니라 정말 model에서 찾기 때문에 값이 존재 하지 않습니다.

 

 

 

'JAVA > Spring' 카테고리의 다른 글

SpringBoot App에 외부 libs 추가  (0) 2023.11.19
[JPA] LockType  (0) 2020.07.23
[Spring] LifeCycle, SmartLifeCycle  (0) 2020.06.23
[MSA] sidecar 패턴  (0) 2020.01.13
[SpringConfig] Properties 암호화  (0) 2019.12.24

댓글()

GraphQL 끄적끄적

DB|2020. 8. 20. 20:17

GraphQL을 들어본것은 오래됬지만, 클라이언트 단에서 질의를 날린다는게 위험할것 같기도 하고

굳이 불필요 할 것 같아 어떻게 사용하고 동작하는지 파악하지 않았었습니다.

 

하지만, 요즘 많은곳에서 사용되는것들을 보며 대략적으로 어떻게 사용하며

어떻게 동작하는지 살펴보려고 합니다.

 

살펴보기 이전에 GraphQL을 사용하는 이유, GraphQL의 강점을 살펴보자면

기존 많이 사용하는 REST API의 경우 각 쿼리에 대해서 url을 설계하고

해당 url으로 주는 값은 언제나 형태가 고정적이였습니다.

하지만, 업무에 따라 필요한 필드가 다름에도, 공개되어있는 API의 응답의 형태는 동일할 것이기 때문에

클라이언트에서 필요없는 데이터 및 필드들은 알아서 필터링해서 사용해야 했습니다.

 

그리고 매번 새로운 형태의 API가 필요하다면 url을 계속해서 추가해야 합니다.

두개의 리소스를 얻기위해서는 두번의 URL 요청을 해야 합니다.

 

하지만, GraphQL을 사용하게 되면, 필요한 필드만을 응답으로 받을수 있고

여러 리소스들을 한번의 요청으로 받아올 수 있습니다.

 

간단하게는, 클라이언트단에서 여러 요청 및 응답을 유연하게 처리할 수 있게 됩니다.

 

일반적으로, GraphQL은 여러 URL이 아닌 하나의 URL을 통해 처리합니다.

(보통 설정으로 path는 수정할 수 있겠지만, 기본값은 /graphql 을 사용합니다.)

 

그리고 모든 리소스, 그리고 모든 필드를 클라이언트가 조회할 수 있게 된다면

보안상 문제가 될수 있기 때문에

graphqls를 확장자의 파일에 정의된 것만 질의 할 수 있게 되어있습니다.

 

제가 작성한 item.graphqls은

schema{
    query: Query
}

type Query{
    allItems: [Item]
    item(id: Float): Item
}

type Item{
    id: Float
    name: String
}

실제로 Item에는 price와 같은 필드들이 존재하지만 graphqls에 Item에는 존재하지 않기 때문에

질의로 얻을 수 없습니다.

 

이에 대응하는 서버 로직을 작성하는 방법은 여러가지가 있겠지만

제가 작성한 방법은 SpringBoot에서 GraphQLQueryResolver를 사용하여 테스트를 진행해 보았습니다.

 

/graphql 로 요청을 보낼때는 GET, POST 모두 지원하지만 요청 방식이 조금씩 다릅니다.

해당 내용은 https://graphql-kr.github.io/learn/serving-over-http/ 을 참고하시면 될것 같으며

 

POST에 대략적인 사용방법은 request content-type은 application/json으로 하고

아래 처럼 바디에 json 형태로 질의를 요청합니다.

{
	"query" : "{result : allItems{id name}}"	
}

위 쿼리는 "allItems를 응답으로 받을껀데, id, name필드를 받을꺼고 result라는 필드에 데이터를 담아서 받고 싶다"가 됩니다.

물론 이것은 테스트로 작성했기에 파라미터 없이 모든 데이터를 받게 했지만

이런 쿼리를 노출한다면, 부하로 인해 문제가 생길수 있겠습니다.

 

이에 응답은 아래와 같은 형태가 됩니다.

{"data":{"result":[{"id":1.0,"name":null},{"id":2.0,"name":null}]}}

 

하나 더 살펴본다면, 아까 언급한것 처럼 기존에는 두번의 요청을 보내야 하는경우를 graphQL은 한번의 요청으로 처리 할 수 있습니다.

{
	"query" : "{result : allItems{id name},result2 : item(id: 1){name}}"
	
}

방금 요청한 모든 Item을 가져오는 결과를 'result'필드로 응답 받고, id 1번에 대한것은 'result2'로 응답을 달라는 질의 입니다(여기서는 같은 item이지만 일반적으로는 같은 리소스가 아니겠지요)

 

 

이에 응답은 아래와 같은 형태가 됩니다.

{"data":{"result":[{"id":1.0,"name":null},{"id":2.0,"name":null}],"result2":{"name":null}}}

 

바로 적용하지는 않을 예정이기 때문에 간단한 사용방법과 사용 까닭 정도 파악을 위해 테스트 해보았고

끄적끄적 정리해보았습니다.

 

추후 더 파악되는 내용 및 기억하기 위해 기록으로 남겨놓을 내용들이 있다면 기록할 예정입니다

감사합니다.

'DB' 카테고리의 다른 글

[DB] 기초부터다시, ACID, CAP  (0) 2020.09.14
기초부터다시, 조인  (0) 2020.08.18
[MongoDB] 해킹된 후 보안 설정 관련  (0) 2019.12.23
[MyBatis] MyBatis 문법 파서  (0) 2019.05.29
DB 스키마를 관리하자  (0) 2018.12.20

댓글()

기초부터다시, 조인

DB|2020. 8. 18. 19:55

Inner Join

'A' INNER JOIN 'B': A,B 교집합

 

Outer Join

'A' LEFT OUTER JOIN 'B' = A

'B' LEFT OUTER JOIN 'A' = B

'A' FULL OUTER JOIN 'B' = A, B 합집합(즉 순서 상관없음)

 

cross join

모든 경우의 수

ON절이 없음

A CROSS JOIN B

SELECT A.field, B.field FROM A, B

 

equal join

동일 값을 중심으로 조인

SELECT A.field, B.field FROM A,B WHERE A.field=B.field

 

Natural join

동일 컬럼을 내부적으로 모두 조인하여 ON 절 생략 가능

SELECT A.field FROM A NATURAL JOIN B

 

조인 연산중 Plan에서 만날수 있는 내부 동작 조인

 

Nested Loop Join

(어딘가에서는 NL Join이라고 불리기도..)

for내에 for 동작과 같음

for(A a : Atable){

  for(B b : Btable){

  }

}

결국 A데이터와 B 데이터가 많을수록 오래걸리는것은 당연하고

A의 값에서 B 값을 찾는데 인덱스가 없으면 코스트(cpu)가 급격히 올라가게 된다

 

 

Sort Merge Join

정렬후 찾는 방식, 연산이 =가 아닌경우 유리한 방식

두 테이블의 크기가 차이가 많이 나면, 소팅하느라 오래 걸리기 때문에 비효율적임

(select에 컬럼 내용 모두 소팅에 포함되어, select 컬럼을 줄이면 도움이 됨)

 

 

Hash Join

해싱 함수를 이용하여 조인 대상을 특정 지역에(partition)에 모아두어 해시값으로 테이블에 조인하는 방식

대용량 처리에 유리

 

 

이미지 출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=26744589

'DB' 카테고리의 다른 글

[DB] 기초부터다시, ACID, CAP  (0) 2020.09.14
GraphQL 끄적끄적  (0) 2020.08.20
[MongoDB] 해킹된 후 보안 설정 관련  (0) 2019.12.23
[MyBatis] MyBatis 문법 파서  (0) 2019.05.29
DB 스키마를 관리하자  (0) 2018.12.20

댓글()