[์ค๋ฅ] Transactional์ ๋ฒ์์์ ๋ฒ์ด๋ dirty checking์ด ๋์ง ์๋ ๊ฒฝ์ฐ
๋ฌธ์ ์ํฉ
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๋ก ์ฎ๊ฒผ์ต๋๋ค