코딩 기록들

게시판만들기 _ AOP, Transaction 본문

카테고리 없음

게시판만들기 _ AOP, Transaction

코딩펭귄 2024. 4. 2. 21:47

@Responsebody의 역할 : 객체 -> JSON으로 변경

1) 비 AJAX ->페이지   2) AJAX -> JSON  --> 두 경우의 처리를 동시에 @Responsebody가 할 수 없다

-> 해결방법 : 예외가 발생한 URL이 어디인가? -> Request라는 객체가 필요함

 

객체를 json으로 바꿔주는 라이브러리

https://mvnrepository.com/artifact/com.google.code.gson/gson -> pom.xml에 추가

 

 

AOP

- 원래있던 코드에 실행전, 실행후 시점에 특정 코드를 실행시키는것

- 공통코드를 원래코드로 넣어주어 동작되게 함 -> AOP는 interceptor와 다른 것

- 파라미터가 무엇이든, 반환타입이 무엇이든 관계없이 알아서 처리해줌

 

* 위빙 

- code1,2,3, a,b,c,d,e 모두 java파일이라면, 이들은 JVM 속에서 complie을 통해 .class가 되어야만 동작될수있다

- weaving(위빙)  = class파일을 조작하는 파일 : .class를 조작! 이미컴파일이 끝난 파일을 조작하는 것

- 위빙을 다르게 해주는 라이브러리 : aspect.jriver ?

 

   a

code1

   b

   c

code2

   d

   e

code3

   f

* a,b,c,d,e,f  위치 : helper code

* -code1,2,3, a,b,c,d,e 모두 java파일

 

* Dependency 추가  https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop/3.2.4

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 

 

AOP클래스 만들기 (TimingAspect.java)
@Aspect // AOP 모듈
@Component // Spring Bean으로 생성
public class TimingAspect {
}

 

 

클래스를 Spring Bean으로 생성시키는 기본 Annotation
@Controller, @Service, @Repository의 부모 Annotation

 

 

 

@Bean, @Component의 차이

- @Bean : 우리가 객체를 만들고 bean 컨테이너에 적재를 시킴 

- @Component : 스프링이 찾아서 객체를 만드는것

 

@Pointcut

- aop를 적용할 대상을 지정

- 즉, 위빙을 해줄 대상을 찾는 일(위빙을 할 대상을 지정)

- execution() : 실행단계에서 적용할 대상을 지정

@Pointcut("execution(public * com.example.demo..service.*ServiceImpl.*(..))")
    private void aroundTarget() {}
// aroundtarget() : pointcut을 주는 역할만 함

- public: public 접근제어자를 사용하는 것을 대상으로 함

- 반환타입 : * (* : 모든 반환타입을 대상으로 함)

- com.forum..service.*ServiceImpl : com.hello.forum아래에 있는 모든패키지 중에서 service패키지 내부에 있는 serviceImpl로 끝나는 모든 클래스를 대상으로 함

- .*(..) : ServiceImpl로 끝나는 모든 클래스 내부의 모든 메소드를 대상으로 함

=> ServiceImpl클래스 밑에 있는 public 모든 반환타입 메소드명()을 대상으로 Aspect를 실행함

 

@Around

- @Around 하나가 @Before, @After, @AfterReturning, @AfterThrowing다 포함

사용예시) 아래 코드 - 원래 실행될 메소드의 전, 후에 공통코드를 실행한다.

- ServiceImpl에 있는 메소드가 실행될 때(Pointcut대상이 실행될 때) 아래 메소드가 실행된다=weaving된 코드가 실행된다

@Around("aroundTarget()")  //Around 하나가 @Before, @After, @AfterReturning, @AfterThrowing다 포함
	public Object timingAdvice(ProceedingJoinPoint pjp) throws Throwable {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		
		Object result = null;
		
		try {
			result = pjp.proceed();
		} catch (Throwable e) {
			//serviceImpl에서 발생한 예외를 그대로 던진다.
			//controller로 예외가 전달되고, 마지막으로 controllerAdvice로 예외가 전달되어
			// 공통예외를 처리할 수 있기 때문
			throw e;
		} finally {
			stopWatch.stop();
			
			//원래 실행되어야하는 클래스
			String classPath = pjp.getTarget().getClass().getName();
			//원래 실행되어야하는 메소드
			String methodName = pjp.getSignature().getName();
			logger.debug("{}.{} 걸린시간: {}ms", classPath, methodName, stopWatch.lastTaskInfo().getTimeMillis());
		}
		return result;
	}

 


Transaction

하나의 Business Logic이 완료/실패 되는 단위

  • 개발자가 말하는 transaction : 하나의 업무 단위
  • DA / DB가 말하는 트랜잭션 : 하나의 쿼리

ServiceImpl.java가 데이터를 Update, Insert, Delete 하는 과정에서

  • 에러가 발생할 경우  : 한 트랜잭션이 처리한 모든 수정 사항을 Rollback
  • 정상 처리한 경우 : 한 트랜잭션이 처리한 모든 수정 사항을 Commit

 

Transaction의 기본원칙 (ACID)

이 4개의 원칙이 지켜져야됨 (DB가 맡아줌)

* 고립성 예시

- 오라클) 변경중인 쿼리에만 lock을 건다

- mysql, mariadb, sqlserver, cubrid, postgresql ) 변경중인 테이블에 lock을 건다 (=select 자체가 안된다)

 

Transaction 처리방법

- Repository로 구성된 Dao를 사용 할 경우 :  Spring에 이미 정의된 Transaction AOP코드가 자동개입함 

   - (단, @Service 클래스의 메소드에 @Transactional Annotation이 정의되어야 함)

      - 롤백이 필요한 부분에만 @Transactional 붙인다! (웬만하면 다 붙이게 됨)

           - select만 할 경우엔 데이터변경이 없으므로 @Transactional안붙여도 됨!

- > serviceImpl 에 있는 메소드 하나하나가 하나의 업무이기 때문에 serviceImpl에 있는 함수 중 select를 제외한 함수에다가 @Transactional 어노테이션 붙여준다!