ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링부트+JPA 블로그 프로젝트 08 스프링 작동 원리 복습
    스프링/스프링부트+JPA - 블로그 2021. 9. 1. 15:32

    유투버 '데어프로그래밍'님 강의 참조

     

    ▲ 전체 흐름

     

    1. 톰켓 시작2. 모든 필터가 메모리에 올라감 → 권한/인증/인코딩 등 걸러야할 것들이 여기서 걸러 짐3. 디스패처가 메모리에 올라감 → 사용자가 요청하는 URL주소를 디스패처가 확인하여 컨트롤러로 뿌림4. 컨트롤러→서비스→JPA레파지토리→영속성 컨텍스트가 차례대로 메모리에 뜸
       (요청에 따라 새로운 C/S/R/C가 뜨게 됨, 하지만 요청(REQUEST)이 와야 메모리에 뜸. 요청없이는 일단 대기 상태)
    5. DataSource하나는 메모리에 뜸 (DS는 DB와 연결되어있음)6. ViewResolver/Intercepter도 메모리에 뜸

     

     

    ☞ 로그인 요청시를 예로 보자

     

    1. 사용자가 로그인 요청(REQUEST)
    'http://localhost:8000/login' 주소로 'POST' 요청 함 → HTTP BODY에 데이터가 담겨서 옴 (username/password)

     

    2. 톰켓→필터→디스패처 작동

     

    3. 디스패처가 컨트롤러중 이 URL주소+PostMapping을 가진 컨트롤러를 메모리에 띄움

     

    4. 컨트롤러는 받으면서 username/password를 같이 받음 (컨트롤러는 함수+파리미터를 만들어서 데이터를 '받는 역할'만 함)

     

    5. 컨트롤러는 이 데이터를 이제 서비스에게 넘기면서 login()을 요청함 

     

    6. 서비스에서 login() 시작 → login()시에 데이터(username/password)에대한 select()질의를 해야하므로 JPA레퍼지토리에게 DB와의 질의를 요청함 (select를 DB에서 해줘)

     

    7. JPA레퍼지토리는 확인을 위해서 함수를 요청함 (쿼리네이밍='SELECT*FROM user WHERE ....')

     

    8. 이 함수요청과 관련된 요청이 영속성 컨텍스트에 있는지 1차 확인 → 제일 처음에는 없으니 DS로 요청 → DS가 DB로 질의 

     

    9. DS가 질의된 결과를 JPA레퍼지토리로 돌려줌과 동시에 영속성 컨텍스트에  'USER-OBJECT'형태로 남게 됨

     

    10. JPA레퍼지토리는 다시 SERVICE에게 질의응답결과를 돌려줌 서비스는 그 결과값이 있는지 아니면 없는지(NULL)에 따라 login()을 시키거나 오류를 띄우고 컨트롤러에 알려주면서 세션에 질의응답이 된 USER값이 등록 됨

     

    11. 컨트롤러는 서비스에서 넘어온 결과가 정상이니 로그인처리가 되고 "/" 이 주소 이하의 페이지를 띄움
    * 이때 컨트롤러의 종류가 중요함   @RestController 이면 데이터를 받는 용, @Controller이면 html페이지를 만들어서 사용자에게 응답하는 용


    12. 단순 페이지(템플릿)를 띄우는 컨트롤러가 발동이 되면 ViewResolver가 작동하게 됨, 즉 @Controller일때는 항상 ViewResolver가 작동 함 

     

    13. 다시말해 @Controller의 리턴값은 항상 주소를 반환 함 'return "/";'

     

    14. @RestController이면 return에 적힌 메세지 자체를 응답해줌 

     

    15. 인터셉터는 어떤 인증이 필요한 요청이 들어오면 이 요청을 한 유저가 세션이 있는지 확인. 필터와 다른점은 필터는 애초에 다 걸러 버린다면, 인터셉터는 나중에 어떤 특정한 함수가 요청되고 그 요청이 중요한 요청(인증등) 일때 발동

     

     

    ☞ 회원가입 요청시를 예로 보자

     

    1.  사용자가 회원가입 요청(INSERT)
       'http://localhost:8000/join' 주소로 'POST' 요청 함 → HTTP BODY에 데이터가 담겨서 옴 (username/password/add...)

     

    2. 톰켓→필터→디스패처 작동

     

    3.  디스패처가 INSERT함수를 가진 컨트롤러를 메모리에 띄움 이때 JDBC에 연결이 자동으로되고 세션이 만들어짐

     

    4.  데이터를 가지고 서비스에 회원가입 요청 서비스단에서 트랜잭션이 발동 

     

    5. 서비스에서 레파지토리에 INSERT()를 요청 최초이니 DB에 바로 INSERT 요청

     

    6. 정상적으로 INSERT가 되면 차례대로 질의응답결과값이 컨트롤러로 가고 컨터를로전 서비스에서 트랜잭션이 실행되면서 메모리에만 떠있던 INSERT값이 COMMIT이 됨 즉 서비스는 트랜잭션이고 이 트랜잭션 관리가 중요

     

    7. 컨트롤러는 최종적으로 RETURN 메세지를 띄우거나(@RestController) 혹은 일반 페이지로 응답 (@Controller)

     

     

     

    ▲ 가장 에매모호한 Service의 역할

    • 그럼 서비스는 트랜잭션만 관리하나? 아니다. 송금을 예로보자

    1) A사용자가 B사용자에게 송금을 요청(REQUEST) 

     

    2) 컨트롤러는 송금(UPDATE)와 데이터를 가진 함수를 발동 서비스에게 송금 요청
       (왜 업데이트일까? A 의 계좌 상태가 송금으로 달라지기 때문)

     

    3) 서비스는 JPA레파지토리에 UPDATE요청 레퍼지토리는 영속성을 체크해서 A오브젝트가 있으면 DB로 가지 않고
       이 영속성에 있는 오브젝트를 업데이트해서 다시 컨트롤러까지 돌아감

     

    4) 이때 서비스에서 트랜잭션이 발동되고 커밋이 됨

     

    5) 이 후 B의 계좌도 업데이트를 해야하는데 똑같은 방식으로 서비스 -> 레파지토리 -> 영속성 OR DB로 요청 함
       하지만 만약 B 업데이트시 오류가 발생하면 ?
       A는 업데이트가 끝나서 500만원이 빠졌지만 B는? 이럴때 필요한게 'ROLLBACK' (제일 처음 아무것도 하지 않는 상태) 

     

     

    -> 즉 서비스는 DB 어떠한 요청과 응답사이에서의 커밋과 롤백을 관리하는 '하나의 기능' 이라고 보면 된다. 서비스는 어떠한 요청과 응답사이에서 하나의 오류라도 있으면 무조건 롤백을 시킨다. 

     

Designed by Tistory.