# 서비스 레이어, 데이터 수정하기
## 미션
---
수정 내용을 전달하여,
![클라우드스터딩-스프링부트-ajax-수정-데이터-전송](https://i.imgur.com/WZVjATB.png)
그 값을 DB에 반영하시오.
![클라우드스터딩-스프링부트-ajax-데이터-수정-확인](https://i.imgur.com/YJf04xf.png)
## 개념
---
#### ⭐️ 서비스 레이어란?
컨트롤러와 리파지터리 사이에 존재하는 영역. 이를 서비스 레이어라 한다. 서비스 레이어는 일련의 처리 순서를 관리한다. 즉, 트랜잭션을 관리한다.
![클라우드스터딩-스프링-부트-서비스(Service)-레이어](https://i.imgur.com/nZ1Ro94.png)
#### ⭐️ 트랜잭션과 롤백
모두 성공되야 하는 일련의 과정. 이를 트랜잭션(transaction)이라 한다. 레스토랑 예약을 예로 들자.
1. 사용 시간 예약
2. 메뉴 선택
3. 자리 선정
4. 지불 방법(카드/무통장/쿠폰) 결정
5. 대금 지급
6. 영수증 발행
7. 예약 체결
고객 A는 현재 지불 방법까지(1~4) 마친 상태. 그런데 대금 지급에 문제가 생겼다면(~~카드 한도 초과~~) 어떻게 해야할까? 다시 말해, 처리된 데이터를 어디까지 되돌려야 할까?
1. 처음부터 모두 다시! 시간 예약부터 진행.
2. 실패 이전 단계부터 다시! 지불 방법 부터 다시 진행.
전자의 경우, 모든 과정(1~7)이 하나 트랜잭션이다. 실패한 경우 모두 초기화 된다. 후자의 경우는, 최소 두 단계의 트랜잭션이 존재한다 볼 수 있다. 여기서 기존 작업이 초기화 되는 것. 이를 롤백(rollback)이라 한다.
![클라우드스터딩-스프링-부트-트랜잭션(transaction)과-롤백(rollback)](https://i.imgur.com/AXYjQDX.png)
## 튜토리얼
---
#### ⭐️ 전체 구조
![클라우드스터딩-스프링부트-서비스-레이어-구조](https://i.imgur.com/uSffd0H.png)
#### ⭐️ 컨트롤러
1) 메소드 내용 추가: "controller/ArticleController"
```
...
@RestController
public class ArticleApiController {
...
@PutMapping("/api/articles/{id}")
public Long update(@PathVariable Long id,
@RequestBody ArticleForm form) {
// 받아온 데이터 확인!
log.info("form: " + form.toString());
// 해당 id로 기존 데이터를 가져옴!
Article target = articleRepository.findById(id)
.orElseThrow(
() -> new IllegalArgumentException("해당 Article이 없습니다.")
);
log.info("target: " + target.toString());
// 재 작성 및 저장!
target.rewrite(form.getTitle(), form.getContent());
Article saved = articleRepository.save(target);
log.info("saved: " + saved.toString());
// 아이디 반환
return saved.getId();
}
}
```
#### ⭐️ 엔티티
2) 메소드 추가: dto/Article
```
...
public class Article {
...
// 내용을 재작성!
public void rewrite(String title, String content) {
this.title = title;
this.content = content;
}
}
```
#### ⭐️ 확인하기
3) 수정 데이터 전송
![클라우드스터딩-스프링부트-ajax-수정-데이터-전송](https://i.imgur.com/WZVjATB.png)
4) 수정 완료
![클라우드스터딩-스프링부트-ajax-데이터-수정-확인](https://i.imgur.com/YJf04xf.png)
#### ⭐️ 리팩토링
5) 서비스 레이어 객체 연결: "api/ArticleApiController"
```
@Slf4j
@RequiredArgsConstructor // final 필드 값을 알아서 가져옴! (@autowired 대체!)
@RestController
public class ArticleApiController {
@Autowired
private ArticleRepository articleRepository;
// 서비스 레이어 연결! 서비스 레이어란?
private final ArticleService articleService;
...
@PutMapping("/api/articles/{id}")
public Long update(@PathVariable Long id,
@RequestBody ArticleForm form) {
Article saved = articleService.update(id, form); // 서비스 객체가 update를 수행
return saved.getId();
}
}
```
#### ⭐️ 서비스 클래스
6) 생성: "service/ArticleService"
```
@Slf4j
@RequiredArgsConstructor
@Service // 서비스 객체 선언! 서비스란?
public class ArticleService {
private final ArticleRepository articleRepository;
@Transactional // 트랜잭션 처리! 트랜잭션이란?
public Article update(Long id, ArticleForm form) {
// 받아온 데이터 확인!
log.info("form: " + form.toString());
// 해당 id로 기존 데이터를 가져옴!
Article target = articleRepository.findById(id)
.orElseThrow(
() -> new IllegalArgumentException("해당 Article이 없습니다.")
);
log.info("target: " + target.toString());
// 재 작성 및 저장!
target.rewrite(form.getTitle(), form.getContent());
Article saved = articleRepository.save(target);
log.info("saved: " + saved.toString());
return saved;
}
}
```
#### ⭐️ 재 확인
7) 수정 데이터 전송 결과
![클라우드스터딩-스프링부트-서비스-레이어-데이터-수정-확인](https://i.imgur.com/h7FI2dn.png)
## 훈련하기
---
- 트랜잭션 관리를 위한 애노테이션 @Transactional. 이를 조사하여 발표하시오.
## 면접 준비
---
- 서비스 객체 무엇? 왜씀?
- 트랜잭션과 롤백이란?