@@ -1,18 +1,21 @@
-package com.antique.service;
+package com.antique.service.review;
 
 import com.antique.domain.Product;
 import com.antique.domain.Review;
-import com.antique.domain.User;
 import com.antique.dto.review.ReviewRequestDTO;
+import com.antique.domain.User;
 import com.antique.dto.user.GetUserReviewDTO;
 import com.antique.exception.BaseException;
 import com.antique.exception.CommonErrorCode;
 import com.antique.repository.ProductRepository;
 import com.antique.repository.ReviewRepository;
 import com.antique.repository.UserRepository;
+import jakarta.transaction.Transactional;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -49,6 +52,7 @@ public List<GetUserReviewDTO> getUserReviews(Long userId) {
     /*
     * 리뷰 작성
     */
+    @Transactional
     public Review createReview(ReviewRequestDTO reviewRequest) {
         User reviewer = userRepository.findById(reviewRequest.getReviewerId())
                 .orElseThrow(() -> new BaseException(CommonErrorCode.USER_NOT_FOUND));
@@ -67,6 +71,65 @@ public Review createReview(ReviewRequestDTO reviewRequest) {
                 .content(reviewRequest.getContent())
                 .reviewDate(LocalDateTime.now())
                 .build();
+
+        updateUserRating(reviewedUser.getUserId());
+
         return reviewRepository.save(review);
     }
+
+    /*
+    * 리뷰 수정
+    */
+    @Transactional
+    public Review updateReview(Long reviewId, ReviewRequestDTO reviewRequest) {
+        Review review = reviewRepository.findById(reviewId)
+                .orElseThrow(() -> new BaseException(CommonErrorCode.REVIEW_IS_NOT_EXIST));
+
+        Long reviewedUserId = review.getReviewedUser().getUserId();
+
+        review.setRating(reviewRequest.getRating());
+        review.setContent(reviewRequest.getContent());
+        review.setReviewDate(LocalDateTime.now());
+
+        updateUserRating(reviewedUserId);
+
+        return reviewRepository.save(review);
+    }
+
+    /*
+    * 리뷰 삭제
+    */
+    @Transactional
+    public void deleteReview(Long reviewId) {
+        Review review = reviewRepository.findById(reviewId)
+                .orElseThrow(() -> new BaseException(CommonErrorCode.REVIEW_IS_NOT_EXIST));
+
+        Long reviewedUserId = review.getReviewedUser().getUserId();
+
+        updateUserRating(reviewedUserId);
+
+        reviewRepository.delete(review);
+    }
+
+    /*
+    * 사용자 평점 update 메서드
+    */
+    public void updateUserRating(Long userId) {
+        List<Review> reviews = reviewRepository.findByReviewedUser_UserId(userId);
+
+        if(reviews.isEmpty()) {
+            userRepository.updateUserRating(userId, 0);
+            return;
+        }
+
+        double averageRating = reviews.stream()
+                .mapToInt(Review::getRating)
+                .average()
+                .orElse(0.0);
+
+        BigDecimal roundedRating = BigDecimal.valueOf(averageRating)
+                        .setScale(1, RoundingMode.HALF_UP);
+
+        userRepository.updateUserRating(userId, roundedRating.doubleValue());
+    }
 }

리뷰: 수정 및 삭제 메소드에 안전한 데이터베이스 작업을 위해서 @Transactional 어노테이션을 붙이면 좋을 것 같아~~

참고자료
https://velog.io/@zedy_dev/Transactional-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98%EC%9D%84-%ED%86%B5%ED%95%9C-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B4%80%EB%A6%AC-%EB%9E%80-%ED%99%9C%EC%9A%A9%EB%B0%A9%EB%B2%95-%EB%82%B4-%EA%B2%BD%ED%97%98