๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ”ฅ ํ”„๋กœ์ ํŠธ/์›จ๋”ฉ๋ฉ”์ดํŠธ

[์˜ค๋ฅ˜] Transactional์˜ ๋ฒ”์œ„์—์„œ ๋ฒ—์–ด๋‚˜ dirty checking์ด ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

by nitronium102 2023. 8. 13.

๋ฌธ์ œ ์ƒํ™ฉ

plannerMapper ์•ˆ์˜ ๋””๋ฒ„๊ทธ๋ฌธ๋“ค์€ ๋ชจ๋‘ ์ˆ˜ํ–‰๋˜๋‚˜ pUsers.updateNickname()์ด ์‹คํ–‰๋˜์ง€ ์•Š์Œ
๋˜ํ•œ insert query๊ฐ€ ๋‚˜๊ฐ€๋‚˜ db์— ๋ฐ˜์˜๋˜์ง€ ์•Š์œผ๋ฉฐ, plannerRepository.save()๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Œ

  • UserService
@Transactional
public void signupPlanner(Users users, PlannerSignupReqDto reqDto) {
	Users pUsers = findUserByEmail(users.getEmail());
	pUsers.updateNickname(reqDto.getNickname());

	Planner planner = plannerMapper.toEntity(pUsers, reqDto);
	plannerRepository.save(planner);
}
  • PlannerMapper
@Component
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public class PlannerMapper {
	private final CategoryMapper categoryMapper;
	private final TagMapper tagMapper;
	private final PlannerTagMapper plannerTagMapper;

	public Planner toEntity(Users users, PlannerSignupReqDto reqDto) {
		Planner planner = Planner.builder()
			.company(reqDto.getCompany())
			.position(reqDto.getPosition())
			.region(reqDto.getRegion())
			.build();

		planner.setUsers(users);
              // ๋””๋ฒ„๊ทธ๋ฌธ1
		Category category = categoryMapper.findCategoryByContentOrElseCreate(CategoryEnum.PLANNER.name());
              // ๋””๋ฒ„๊ทธ๋ฌธ2
		List<Tag> tagList = reqDto.getPlannerTagList()
			.stream().filter(Objects::nonNull)
			.map(content -> tagMapper.contentToEntity(content, category))
			.toList();
              // ๋””๋ฒ„๊ทธ๋ฌธ3
		List<PlannerTag> plannerTagList = tagList
			.stream().filter(Objects::nonNull)
			.map(tag -> plannerTagMapper.plannerToEntity(planner, tag))
			.toList();
              // ๋””๋ฒ„๊ทธ๋ฌธ4
		planner.createPlannerTagList(plannerTagList);
              // ๋””๋ฒ„๊ทธ๋ฌธ5
		return planner;
	}
}

 

๋ฐœ์ƒ ์›์ธ

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋Š” ๋ณดํ†ต ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ง์€ ์ฆ‰, @transactional ์• ๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ๋ฉ”์„œ๋“œ์˜ ์‹œ์ž‘๋ถ€ํ„ฐ ์ข…๋ฃŒ๊นŒ์ง€๊ฐ€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•˜๋ฉด ์ด ์—”ํ‹ฐํ‹ฐ๋Š” ์˜์† ์ƒํƒœ๊ฐ€ ๋˜์–ด ๋ณ€๊ฒฝ ๊ฐ์ง€(dirty checking) ๋“ฑ JPA์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณต๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 JPA์˜ dirty checking์€ @transactional์ด ๋ถ™์€ ๊ณณ์—์„œ๋งŒ ์ž‘๋™ํ•˜๋Š”๋ฐ, plannerMapper์—๋Š” ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์–ด์žˆ์ง€ ์•Š์•„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๊ด€๋ จ ์„ค์ •์ด ๋จนํžˆ์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ planner.setUsers() ์„ค์ •์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๊ณ , ์ด์— ๋”ฐ๋ผ ๋ฐ˜ํ™˜๋œ planner ์—ญ์‹œ ์ œ๋Œ€๋กœ db์— ๋ฐ˜์˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
transactional ์‹คํ–‰ ๊ณผ์ • ์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์œผ๋ฏ€๋กœ ๊ด€๋ จ ๋ณ€๊ฒฝ์‚ฌํ•ญ๋“ค์€ ๋ชจ๋‘ ๋ฐ˜์˜๋˜์ง€ ์•Š์•„ pUsers.setNickname()๋„ ๋ฐ˜์˜๋˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ์ถ”์ธก๋ฉ๋‹ˆ๋‹ค.

 

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

planner.setUsers(users); ๋ฅผ mapper์—์„œ @transactional์ด ์ ์šฉ๋˜๋Š” signupPlanner๋กœ ์˜ฎ๊ฒผ์Šต๋‹ˆ๋‹ค

๋Œ“๊ธ€