@Transactional 사용

SoDEV·2025년 7월 1일

스프링 부트

목록 보기
14/18

Transaction 이란?

  • DB 상태 변화를 위해 수행하는 작업 단위

ACID

  1. A : ATOMICITY
    • 데이터 read,write,update,delete를 하나의 단위로 실행
  2. C : Consistency
    • 변경사항을 적용할 때 정의된 방식만 사용
  3. I : Isolation
    • 여러 사용자가 같은 테이블에서 동시에 작업(READ,WRITE)할 경우 각각의 트랜젝션을 분리함
      -> 이를 통해 하나씩 발생하도록 함
  4. D :Durability
    • 트랜젝션 실행으로 인해 data에 적용된 변경사항이 저장되도록 보장한다.

Transactional 없는 코드

  1. ArticleController

    @DeleteMapping("/api/articles/like/{id}")
    public ResponseEntity<Void> deleteLike(@PathVariable long id,Principal principal){
        Like like=articleService.findByLikeId(id);
    
        Article article=articleService.findById(like.getArticle().getId());
        articleService.deleteLike(id,principal.getName());
        System.out.println("Delete controller에서의 상태: "+article.getLikeCnt());
        return ResponseEntity.ok().build();
    }
    • 취소 클릭
      ->Delete controller에서의 상태: 0
  2. ArticleViewController

        @GetMapping("/articles/{id}")
    public String getArticle(Authentication authentication,@PathVariable Long id, Model model){
        Article article = articleService.findById(id);
        Like like=null;
        ...
           System.out.println("현재 article View에서 좋아요 리스트: "+article.getLikeList());
        System.out.println("현재 article에서 좋아요 수 :"+article.getLikeCnt());
        model.addAttribute("article",article);
        return "article";}
  • 취소 클릭
    -> 현재 article View에서 좋아요 리스트: [] 현재 article에서 좋아요 수 :1
    ->💥 servicearticleController과는 다른 결과이다.
  1. ArticleService

     public void deleteLike(long id,String userName){
        //본인 글만 삭제 가능
        Like like = likeRepository.findById(id).orElseThrow(()->new IllegalArgumentException("not found: "+id));
        Article article=articleRepository.findById(like.getArticle().getId()).orElseThrow(()->new IllegalArgumentException("not found"+like.getArticle()));
        if(like.getUserName().equals(userName)) {
            likeRepository.deleteById(id);
            article.deleteLikeCnt();//function에서 미리실행?
    
        }
        else{
            throw new IllegalArgumentException("좋아요 한 사람 아님!");
        }
    
        System.out.println("좋아요 취소 후service에서 articleCnt 상태?"+article.getLikeCnt());
    }
    • 취소 클릭후
      좋아요 취소 후service에서 articleCnt 상태: 0

좋아요 클릭 후

좋아요 취소 후

Transactional 있는 코드

변경 코드


@Transactional //트랜잭션 -> 데이터베이스 변경 작업 단위
public void deleteLike(long id,String userName){
}
  1. 좋아요 취소 후service에서 article 상태 : 0
  2. Delete controller에서의 상태: 0
  3. 현재 article View에서 좋아요 리스트: [] 현재 article에서 좋아요 수 :0

    결과 화면

  • 좋아요 클릭 후
  • 좋아요 취소 후

참고
https://www.databricks.com/kr/glossary/acid-transactions

profile
비가 와도 눈이 와도 파도를 향해서! 🌊🐢

0개의 댓글