TIL - save() & saveAndFlush() | Exception (checked & unchecked) | AWS S3 Bucket 사용해보기

su·2023년 8월 4일
0

TIL

목록 보기
58/93
post-thumbnail

repository의 save()와 saveAndFlush()

아무런 생각 없이 JpaResitory의 save() 만 사용하다가,
saveAndFlush() 라는 메소드도 있다는 것을 알게 되었다.

둘 다 엔티티를 저장하는 것으로 보이는데, 차이가 뭐가 있을까 ..?

save()

@Transactional
@Override
public <S extends T> S save(S entity) {

	Assert.notNull(entity, "Entity must not be null");

	if (entityInformation.isNew(entity)) {
		em.persist(entity);
		return entity;
	} else {
		return em.merge(entity);
	}
}

saveAndFlush()

@Transactional
@Override
public <S extends T> S saveAndFlush(S entity) {

	S result = save(entity);
	flush();

	return result;
}

두 메소드의 차이는 flush() 여부였다.
flush()를 날리면 영속성 컨텍스트에서 DB 트랜잭션 쪽으로 쿼리문이 날라가게 된다.

그러니까, 메소드 실행 시, flush()를 바로 날려서 DB 트랜잭션으로 쿼리문이 날라가도록 하냐, 하지 않냐의 차이!

commit은 .. JPA에서 알아서 해주는 건가보다 ..

Checked Exception / Unchecked Exception

Error / Exception

오류는 에러(Error) 와 예외(Exception)으로 나눌 수 있다.
에러(Error) : 시스템 레벨에서 발생하는 심각한 수준의 오류. 개발자가 미리 예측할 수 없으므로 개발 시 신경쓰지 않아도 되는 점.
예외(Exception) : 로직에서 발생하는 오류. 개발자가 구현한 코드에서 발생하므로 개발자가 미리 예측할 수 있고, 상황에 맞게 처리할 수 있음.

Checked Exception / Unchecked Exception

Exception은 크게 두 가지로 나눈다. Checked와 Uncheked로 나눈다.

Checked ExceptionUnchecked Exception
애플리케이션 예외 처리반드시 예외 처리 코드가 있어야 함강제는 아님
예외 발견 시점컴파일 시점런타임 시점
Rollback 여부Rollback XRollback O
대표 클래스Exception을 상속받는 클래스 중, RuntimeException을 제외한 예외클래스 (ex. IOException, SQLException)RuntimeException을 상속받는 모든 클래스 (ex. NullPointerException, IllegalArgumentException)

Rollback 여부

Checked Exception과 Unchecked Exception의 차이점 중 하나인 Rollback 여부이다.
Checked Exception은 Rollback이 되지 않는다.
이는 Spring이 EJB 관습을 따르기 때문이라고 한다.

EJB (Enterprise Java Bean) 란 ?

  • 기업 환경의 시스템을 구현하기 위한 서버 측의 컴포넌트 모델
  • 일반적으로 업무 로직을 갖고 있는 서버 어플리케이션을 부르는 말
  • Enterprise Bean: 비지니스 로직을 탑제한 부품
  • 컨테이너: Database 처리, Transaction 처리 등 시스템 서비스를 이용한 로직을 감추고 있는 부품

반면, 에너테이션을 사용하든 AOP 설정을 하든 Spring은 Uncheked Exception과 Error 발생 시 Rollback하는 것을 기본 원칙으로 따른다.
(Checked Exception은 컴파일 시 확인 가능하므로 이 예외에서는 Rollback을 해주지 않는 듯 하다..!)

하지만 Checked Exception에서 항상 Rollback이 안되는 것은 아니고, 가능하게 설정할 수 도 있다.

1. @Transactional 에너테이션에 옵션 추가하기

@Transactional(rollbackFor = Exception.class)

2. RollbackRuleAttribute를 이용해 롤백 규칙 추가하기

Spring에 존재하는 RollbackRuleAttribute 클래스가 있는데,
이 타입의 리스트에 Exception을 추가해주면 된다 !

<참고>

S3에 이미지 업로드하기 (Spring boot)

1) S3 Bucket 생성하기

먼저, AWS에 S3 Bucket을 생성한다.
버킷 이름에는 언더바(_)대문자(A-Z)를 사용할 수 없다!
(나는 객체 소유권은 권장으로 설정했다.)

2) IAM 사용자 권한 추가하기

방법을 많이 찾아보았는데, 나는 S3 Bucket을 만들기 전에 IAM을 먼저 만들어두었기 때문에 권한 설정을 따로 해주지는 않았다.
즉 처음에 IAM 사용자를 만들 때, 권한을 이미 부여했기 때문에 따로 권한을 줄 필요가 없었다.
다만, 엑세스 키는 생성해주어야 한다 !
그래야 접근할 수 있기 때문이다.
생성된 엑세스 키에 대한 내용은 꼭 !!! 꼭 !! csv 파일로 저장해두어야 한다.

3) build.gradle에 의존성 추가하기

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

aws를 사용하기 위한 의존성을 추가해준다. (gradle 기반)

4) application.properties 파일 작성하기

application.properties에 위에서 만든 Bucket엑세스 키에 대한 정보를 입력한다.
조심해야 할 것은, gitHub에 절대절대절대 올리면 안된다는 것이다.
공개적으로 올려버리면, 해킹당할 위험이 있기 때문이다.
나는 .gitignore에 미리 application.properties 파일을 올려두었다.

// 경로가 기억이 안난다 ..
..경로/..경로/application.properties

해당 파일의 경로에 맞춰서 넣어주기만 하면 된다 !
이미 gitHub에 올라간 상태라면 파일 내용을 미리 복사해두고, gitHub에서 삭제했다가 pull 해와서 ignore에 코드를 추가하고, 다시 application.properties 파일을 만들어주면 된다!
(다른 내용들은 미리 commit 꼭 해둬야 날라가지 않는다)

# S3
cloud.aws.credentials.accessKey={자신의 accessKey}
cloud.aws.credentials.secretKey={자신의 secretKey}
cloud.aws.s3.bucket={만들어진 Bucket의 이름}
cloud.aws.region.static=ap-northeast-2 // 지역을 넣으면 된다
cloud.aws.stack.auto-=false

5) S3Config 파일 작성하기

@Configuration
public class S3Config {
    @Value("${cloud.aws.credentials.accessKey}")
    private String accessKey;

    @Value("${cloud.aws.credentials.secretKey}")
    private String secretKey;

    @Value("${cloud.aws.region.static}")
    private String region;

    @Bean
    public AmazonS3 amazonS3Client() {
        AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);

        return AmazonS3ClientBuilder
                .standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withRegion(region)
                .build();
    }

}

AmazonS3를 사용하기 위해서 S3Config 파일을 작성해준다.
application.properties에 미리 작성해두었던 값들을 가져와 AmazonS3Client 객체를 만들고,
Bean으로 주입하여 사용할 수 있게 만들어준다!

profile
(❁´◡`❁)

0개의 댓글