Home
>
Spring
>
๐[Spring] `@Transactional`์ด read ๋ฉ์๋์ ๋ถ์ด์์ง ์์ ์ด์ ๋ ๋ฌด์์ผ๊น์?
Spring
Framework
๐[Spring] @Transactional
์ด read ๋ฉ์๋์ ๋ถ์ด์์ง ์์ ์ด์ ๋ ๋ฌด์์ผ๊น์?
๐ Intro ๋ฐ ์ฝ๋ ์๊ฐ.
package kobe.board.article.service;
import kobe.board.article.entity.Article;
import kobe.board.article.repository.ArticleRepository;
import kobe.board.article.service.request.ArticleCreateRequest;
import kobe.board.article.service.request.ArticleUpdateRequest;
import kobe.board.article.service.response.ArticleResponse;
import kobe.board.common.exception.CustomException;
import kobe.board.common.responsecode.ResponseCode;
import kuke.board.common.snowflake.Snowflake;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class ArticleService {
private final Snowflake snowflake = new Snowflake();
private final ArticleRepository articleRepository;
@Transactional
public ArticleResponse create(ArticleCreateRequest request) {
ArticleResponse article = createArticle(request);
return article;
}
private ArticleResponse createArticle(ArticleCreateRequest request) {
// 1. ๊ฒ์๊ธ ์์ฑ ๋ฐ ์ ์ฅ
articleRepository.save(
Article.create(snowflake.nextId(), request.getTitle(), request.getContent(), request.getBoardId(), request.getWriterId())
);
// 2. ๊ฒ์๋ฌผ ์ฌ/๋ถ ๊ฒ์ฆ.
Article article1 = articleRepository.findById(snowflake.nextId()).orElseThrow(() -> new CustomException(ResponseCode.NOT_FOUND_ARTICLE));
// 3. ArticleResponse ๋ฆฌํด
return ArticleResponse.from(article1, ResponseCode.SUCCESS_CREATE_ARTICLE);
}
@Transactional
public ArticleResponse update(Long articleId, ArticleUpdateRequest request) {
// 1. ๊ฒ์๋ฌผ ์ฌ/๋ถ ๊ฒ์ฆ.
Article article = articleRepository.findById(articleId).orElseThrow(() -> new CustomException(ResponseCode.NOT_FOUND_ARTICLE));
// 2. ๊ฒ์๋ฌผ ์
๋ฐ์ดํธ.
article.update(request.getTitle(), request.getContent());
// 3. ArticleResponse ๋ฆฌํด.
return ArticleResponse.from(article, ResponseCode.SUCCESS_UPDATE_ARTICLE);
}
public ArticleResponse read(Long articleId) {
return ArticleResponse.from(articleRepository.findById(articleId).orElseThrow(), ResponseCode.SUCCESS_READ_ARTICLE);
}
@Transactional
public void delete(Long articleId) {
articleRepository.deleteById(articleId);
}
}
- โ๏ธ ์ ํด๋์ค๋ ๊ฒ์๋ฌผ ์๋น์ค ํด๋์ค์.
- โ๏ธ ๊ฒ์๋ฌผ ์์ฑ, ์
๋ฐ์ดํธ, ์ญ์ ๊ด๋ จ ๋ฉ์๋์๋
@Transactional
์ด ๋ถ์ด์๋๋ฐ read
๋ฉ์๋์๋ ๋ถ์ด์์ง ์์.
โ
1๏ธโฃ @Transactional
์ด read
๋ฉ์๋์ ๋ถ์ด์์ง ์์ ์ด์ .
โ
1๏ธโฃ @Transactional
๊ธฐ๋ณธ ๊ฐ๋
.
- โ๏ธ
@Transactional
: ํธ๋์ญ์
๊ด๋ฆฌ๋ฅผ ์ํด ์ฌ์ฉ๋๋ฉฐ, ์ฃผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ผ๊ด์ฑ์ ์ ์งํ๊ธฐ ์ํด ์ฌ์ฉ๋จ.
- โ๏ธ ์ฝ๊ธฐ ์ ์ฉ(read-only) ํธ๋์ญ์
:
readOnly = true
๋ก ์ค์ ํ๋ฉด ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์์ด ์กฐํ๋ง ์ํํ๊ฒ ๋จ.
โ
2๏ธโฃ read
๋ฉ์๋์ @Transactional
์ด ํ์ํ์ง ์์ ์ด์
1๏ธโฃ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์์.
- โ๏ธ read ๋ฉ์๋๋ ๋จ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ๋ง ํ๊ณ ๋ณ๊ฒฝํ์ง ์๋๋ค.
- โ๏ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ธฐ ์์
(INSERT, UPDATE, DELETE)์ด ์๊ธฐ ๋๋ฌธ์ ํธ๋์ญ์
์ด ํ์ํ์ง ์๋ค.
2๏ธโฃ ์ฑ๋ฅ ์ต์ ํ
- โ๏ธ ํธ๋์ญ์
์ ๋ฆฌ์์ค๋ฅผ ์๋ชจํจ.
- โ๏ธ ๋ถํ์ํ ํธ๋์ญ์
์ ์ฌ์ฉํ๋ฉด ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ ์ ์์.
- โ๏ธ read ๋ฉ์๋๋ ํธ๋์ญ์
์ ์ฌ์ฉํ ํ์๊ฐ ์์ด, ๋ ๊ฐ๋ณ๊ณ ๋น ๋ฅด๊ฒ ์๋ํจ.
3๏ธโฃ ๊ธฐ๋ณธ์ ์ผ๋ก JPA๋ ์ฝ๊ธฐ ์์
์์ ํธ๋์ญ์
์ด ํ์ ์์
- โ๏ธ JPA๋ ์ฝ๊ธฐ ์์
๋ง ์ํํ ๊ฒฝ์ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ํธ๋์ญ์
์ ํ์๋ก ํ์ง ์์.
- โ๏ธ
findById
๋ ์ฝ๊ธฐ ์ ์ฉ ์์
์ด๊ธฐ ๋๋ฌธ์ ๋ณ๋์ ํธ๋์ญ์
์ค์ ์ด ํ์ ์์.
โ
3๏ธโฃ @Transactional(readOnly = true)
๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ.
- โ๏ธ
@Transactional(readOnly = true)
๋ฅผ ์ฌ์ฉํ๋ฉด ์์์ฑ ์ปจํ
์คํธ๋ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ค์ ๋๋ค.
- โ๏ธ read ๋ฉ์๋๋ ๋ช
์์ ์ผ๋ก
@Transactional(readOnly = true)
๋ฅผ ์ถ๊ฐํ ๊ฒฝ์ฐ, ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ด ์๋ค.
- โ๏ธ ์ฑ๋ฅ ์ต์ ํ : ์ฐ๊ธฐ ์ฐ์ฐ์ ์ฐจ๋จํ๊ณ , ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ต์ ํ๋๋ค.
- โ๏ธ ์์ ์ฑ : ์๋ชป๋ ์ฐ๊ธฐ ์ฐ์ฐ์ด ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํ๋ค.
๐ฏ ์์: read ๋ฉ์๋์ @Transactional(readOnly = true)
์ ์ฉ
@Transactional(readOnly = true)
public ArticleResponse read(Long articleId) {
return Articleresponse.from(
articleRepository.findById(articleId)
.orElseThrow(
() -> new CustomException(ResponseCode.NOT_FOUND_ARTICLE)
),
ResponseCode.SUCCESS_READ_ARTICLE
);
}
โ
4๏ธโฃ ์ํฉ๋ณ @Transactional
์ฌ์ฉ ์ฌ๋ถ.
๋ฉ์๋ ์ ํ |
@Transactional ํ์ ์ฌ๋ถ |
์ด์ |
Create |
ํ์ํจ |
๋ฐ์ดํฐ ๋ณ๊ฒฝ ๋ฐ์(INSERT) |
Update |
ํ์ํจ |
๋ฐ์ดํฐ ๋ณ๊ฒฝ ๋ฐ์(UPDATE) |
Delete |
ํ์ํจ |
๋ฐ์ดํฐ ๋ณ๊ฒฝ ๋ฐ์(DELETE) |
Read(์กฐํ๋ง) |
๋ถํ์ |
๋ฐ์ดํฐ ๋ณ๊ฒฝ ์์(SELECT) |
Read(๋ณต์กํ ์กฐํ) |
@Transactional(readOnly = true) ๊ถ์ฅ |
์ฝ๊ธฐ ์ ์ฉ ์ต์ ํ ๋ฐ ์์ ์ฑ |
๐ ๊ฒฐ๋ก .
- โ๏ธ read ๋ฉ์๋์๋ ๊ธฐ๋ณธ์ ์ผ๋ก
@Transactional
์ด ํ์ํ์ง ์์.
- โ๏ธ ํ์ง๋ง ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์์ ์ฑ์ ๋์ด๊ณ ์ต์ ํ๋ฅผ ์ํ๋ค๋ฉด
@Transactional(readOnly = true)
๋ฅผ ์ฌ์ฉํด๋ ๋จ.
๐ ๊ถ์ฅ ์ ๊ทผ๋ฒ.
- โ๏ธ ๋จ์ ์กฐํ๋ผ๋ฉด
@Transactional
์ ์๋ตํด๋ ๋ฌด๋ฐฉํจ.
- โ๏ธ ์ฝ๊ธฐ ์ต์ ํ๋ ์ถ๊ฐ ์์ ์ฑ์ด ํ์ํ๋ค๋ฉด
@Transactional(readOnly = true)
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์.