'주문'을 insert하는 서비스를 만든다고 해보자.
- 이때 사용되는 data는 하나가 아님
'결제' 서비스를 만든다고 해보자.
- (사실 결제는 '주문' 테이블에 들어감)
- 결제 정보 입력 ... and?
- 사용자가 결제할 때 포인트같은걸 썼을 수도
-> 포인트, 쿠폰 사용에 대한 업데이트
-> 포인트 up .... 등등등등
- '포인트 차감'이라고 하면 이것에 대한 것만(!) 되서는 안 됨.
전체가 다 되어야 함. (포인트 차감, 쿠폰 차감... 이런 것들이 '다')
구현 할 때는 어떻게?
cf) 만약 jdbc 였다면 com.setAutoCommit(false) ... 안에다가 다 함수들 적어주고 com.commit(); 해주면 된다고 생각할 수도 있으나 ... 이게 불가능하다. (각각 commit 된 상태라서)
con. (connection)을 공유하고 있어서
-> connection 의 이 문제를 해결한게 바로 EJB (서버임)
EJB에 Dao 등록
Dao 생성은 EJB 서버가 생성
EJB 서버 안에 Container. 설정을 잘해줘야!! Dao가 다운되지 않고 잘 실행됨 (쉽게 다운된다고 함ㅠ)
- Dao를 EJB라고 하고 EJB 컨테이너 안에 올리는데 자꾸 다운된다고....
vs 우리가 만든 Dao는 심플.
-> 그럼에도 불구하고 올려야하는 이유는 connection 때문 ㅠ
하나의 connection을 유지할 수 있도록 하게 / 그래서 물려서! 한 번에 처리해주는 트랜잭션을 위해...
갈등... EJB 쓰자니 성능이 안 좋고, 안 쓰자니 또 그렇고...
유튜브에 영상 8개로 있음
AOP가 왜 필요한지만 이해하면 전혀 어렵지 않다. 모든 메소드의 호출 시간을 측정하고 싶다면? - 상황 가정 : 초마다 다 코드 만들어놨는데 갑자기 상사가 ms로 바꾸라고 해서 다시 다 수정해야 하는 상황 메소드가 1억개라면? ... ... 이렇게 시간 찍는건 '핵심 기능'이 아님. - 여러 메소드의 공통적인 문제임 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern) - 시간 측정 : 공통 관심 사항 - 각 메소드들 : 핵심 관심 사항 이 둘이 섞여져 있어서 유지 보수가 정말 힘듦 출처 : https://ubermensch-with.tistory.com/394?category=938522 |
코드를 필요하면 꽂았다가, 필요하지 않으면 꽂아넣지 않도록 하기
-> AOP가 쉽게 해준다 :)
AOP 용어를 알아보자.
핵심 관심 사항 / 주업무 : core/primary concern (각 메소드들!)
공통 관심 사항 / 부업무 : cross-cutting concern
빵또아.
Q. 어떻게 한 번 만든걸 (공통핵심사항) 모든 함수의 빵또아의 빵 위치에 꽂을 수 있을까?
Proxy 클래스를 둔다.
- 그리고 cross-cutting concern 클래스 준비.
한 번 만들어 놓으면 되는거지~ :)
(빵또아 공장 느낌ㅎㅎ)
왼쪽 보라색 점은 '호출 함수' 어떤거든 main 함수든 (예를 들어 이 과정을 f1() 함수라고 하면) f1() 함수를 호출해주는 것
//
예제
cross vs core 나눠주기!
Q. proxy 자료형이 Exam인가?
// 만들어보자.
javaPrj
패키지명 com.newlecture.entity
클래스 추가 - NewlecExam implements Exam
세팅해주고 (4단계)
패키지명 com.newlecture.entity
인터페이스 추가 - Exam
package com.newlecture.entity;
public interface Exam {
int total();
float avg();
}
package com.newlecture.entity;
public class NewlecExam implements Exam {
private int kor;
private int eng;
private int math;
public int total() {
int result = kor + eng + math;
return result;
}
public float avg() {
float result = total()/3.0f;
return result;
}
}
// AOP 전혀 염두해두지 않는다면
App에 main 함수 있는데
Exam exam = new NewlecExam();
System.out.println(exam.total());
-> 실행하면 0이 나옴
// 스프링
'앞 뒤로 log를 남기고 싶다'면?
-> Proxy 코드를 추가하자.
core를 흉내내는 가짜 클래스.
NewlecExam을 똑 닮은 가짜 instance 생성 가능
- 진짜도 만들어줘야하고
- 흉내내서 사용할 수 있는 껍데기를 만들어주기도...
- 핸들러같은것도 만들어줘야...
가짜를 만들어보자!
Exam exam = Proxy.newProxyInstance(null, null, null);
- exam은 가짜인지 찐짜인지를 모르고 호출하게 됨.
Spring DI.
Proxy 생성하는데 훨씬 더 유연하게 해준다.
class 정보를 통해서
자료형에 맞는 인터페이스 정보를 줘야. new Class[] (Exam.class),
new InvocationHnadler <- 익명객체로 해주는 중...
exam.total에서 exam은 가짜!
30번째줄을 안해주면 null만 retrun하는거고, 이걸 해줘야함!!
- 만약 이 위에 System.our.println("하하")를 입력 / 아래다가 "호호"를 하면 이게 빵 부분
- 이게 아이스크림 부분인 것!
다시 아까 하던거로 돌아오면 ~
57 - 58번재줄 사이에 하나만 추가해주면 됨
-> @Transactional
Q. 트랜잭션을 처리한다는건? 4가지를 처리하는 것
-> ACID
A 원자성 - '원자성전파'에 대해 알아야.
C 일관성 - 데이터 결함 발생하지 않도록
I 고립성 - 여러 요청 들어왔을 때 다른 사람의 개입 없이 하도록
D 지속성 - 천재지변으로 전기가 나가도 내가 commit한 내용은 저장되어야
https://ubermensch-with.tistory.com/370
//
Dao 이용해서 2개 서비스 넣어보자.
일부러 오류 내 본 상황
- wirterId를 실제 존재하지 않는걸 넣어준 것
- FK
서버 실행해서 -> 수정 -> update 하기 위해 '저장' 누르면 오류남
transaction이 깨졌는지가 포인트
hit가 100일가 0일까
우리가 기대했던 값은 0.
- 억지로 2번의 update를 했잖아.
2번의 update를 다 했다면 hit는 0이 되어야 하잖아.
-> 그러니 잘못된 것 (지금 100 나왔으니)
취소가 되서 0이 되었어야 정상. (원래 0이었음)
- 실행하면 100 되면 안 됨.
- 오류나서 반쪽 날라간 상태인데...
@Transactional 쓰면 (@Override 위에)
-> 또 오류
콘솔창 결과 보기
-> 콘솔창에서는 아래처럼 나도 나오는데 0이 나오는걸 어떻게 확인하지? MySQL 들어가서 확인인가?
-> 그렇다.
92032880 (내가 실행한 id)
원자성을 잘 지켜주는 중
- 오류면 -> 복구 해놔야
cf) 아까 100이 나온건 transation이 깨진거 (둘 다 안되면 다 안되어야지)
@Transactional 안 썼을 때는
-> 100이 삽임됨
이러면 지금 원자성 '위반' 되는것. 안 되면 다 안되어야지.
update 지금 2개지 (일부러 오류내도록 써준거는 주석처리)
MyBatisNoticeDao를 가보자.
요지는! NoticeDao에서도 2개 같이 해줘야할 상황이 있을 수 있겠구나~
NoticeServiceImp
@트랜잭션
-> 지켜짐 (에러가 나면 원래대로 돌아감)
Q. 둘 중 뭘까? 트랜잭션 유지될까?
1. 원래대로 돌아간다 (hit=1)
2. 아래단에서 나는 오류는 상관없다. 그래서 hit=200 나올것이다.
100, 200 나오는게 최악이지 (원자성 위반되는거니까)
확인은... 두둥!
//
아래단에서의 트랜잭션도 다 처리.... OK.
근데 만약 아래단에서 '나한테 신경쓰지마!' 하는 옵션도 있다.
이건 내일!
79일 - 인증과 권한. 1.인증 설정 2.권한 설정- 1) 인메모리 방법 2)db 방법 with 사용자 정보, 사용자 역할 정보 (0) | 2021.06.11 |
---|---|
79일 - @Transactional의 '전파 모드' & ACID 中 2) 고립도 설정 (0) | 2021.06.11 |
78일 - Service 구현 (프로젝트 관련) (0) | 2021.06.10 |
78일 - 단위 테스트 (0) | 2021.06.10 |
78일 - 다수의 db 가져오기 <foreach> (0) | 2021.06.10 |