refactor/feat: Post·PostImage B 구조 적용(트랜잭션 분리) — create · update 동시 반영 + 테스트 픽스처 안정화#135
Merged
refactor/feat: Post·PostImage B 구조 적용(트랜잭션 분리) — create · update 동시 반영 + 테스트 픽스처 안정화#135
Conversation
- 모든 테스트 픽스처에 nickname을 UUID suffix로 생성하여 UNIQUE(23505) 충돌 방지 - password 컬럼 필수값 추가 세팅으로 무결성 위반(23502) 예방 - 관련 테스트(assert) 보정: 고정 닉네임 비교 → 생성값/접두어 기반 비교로 안정화 - 영향 범위: comments/postImages/postLikes/posts의 Entity/Repository 테스트 전반
- 업로드 전용 uploadImagesOnly()로 S3 I/O를 TX 밖으로 분리 - DB 전용 saveImageUrls()로 URL만 짧게 반영 - cleanupUploadedOnRollback()로 TX 롤백 시 업로드분 S3 정리 - deleteS3ByUrlsQuietly() 유틸 도입(예외 삼키고 warn 로깅)
- uploadImagesOnly로 업로드 선행(트랜잭션 유지하되 DB 커넥션 미점유) - cleanupUploadedOnRollback 등록 후 post/saveImageUrls로 URL만 DB 반영 - 첫 이미지로 썸네일 설정 로직 유지
- deleteSelectedImagesDbOnly(postId, urls): DB-only 삭제, 실제 삭제된 URL 반환 - deleteS3QuietlyAfterCommit(urls): 커밋 이후 S3 정리(예외 삼킴) - deleteSelectedImages(...): 래퍼 → DB-only 후 afterCommit S3 호출
- findFirstImageByPostId 제거(미사용) - findImagesByPostId @transactional(readOnly = true) 추가 - deleteAllByPost: DB 먼저 삭제 → 커밋 후 S3 정리(deleteS3QuietlyAfterCommit)로 전환
- updatePost: 업로드 선행(uploadImagesOnly) 후 TX 내 mutateImagesAndRefresh로 일괄 처리 · cleanupUploadedOnRollback, deleteSelectedImagesDbOnly(DB-only), saveImageUrls(URL DB 저장) · 썸네일 refreshThumbnailIfNeeded(남은 이미지 < 2면 예외), 기존 유지/필요 시 갱신 · 텍스트는 썸네일 결정 이후 applyTextIfChanged, 변경 없으면 save 스킵(no-op) - 조회: getPostById / findByStoreId / findByStoreIdWithCommentsAndLikes에 @transactional(readOnly = true) 추가 · dirty checking 완화 + LAZY 접근 트랜잭션 경계 보장
- title/content가 실제로 달라질 때만 값을 갱신하고 변경 여부(boolean) 반환 - updatePost에서 텍스트 무변경 시 save 스킵 가능해져 JPA flush/쓰기 부하 감소
… — 퍼블릭 엔트리포인트에서 트랜잭션 시작하도록 정리
…IRES_NEW) 적용 — 이미지 삭제를 독립 트랜잭션으로 격리해 상위 롤백 영향 최소화
… 세분화로 테스트 보정 - create/update 오케스트레이션·트랜잭션·이미지 변이 단계 분리 및 플래그 도입 - PostImageService 메서드 분리(uploadImagesOnly/saveImageUrls/deleteSelectedImagesDbOnly 등) - savePostImages 의존 제거 후 신규 API 기준 스텁·검증 교체 - 통합 테스트 “진짜 흐름” 적용(최소 2장 규칙/썸네일 재평가) - AppLogger NPE·불필요 스터빙 제거
Merge branch 'dev' of https://github.com/pinup-team/pinup into feat-posts
|
✅ 테스트 통과! |
src/test/java/kr/co/pinup/postImages/service/PostImageServiceIntegrationTest.java
Outdated
Show resolved
Hide resolved
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약
PostService.createPost,PostService.updatePost둘 다 B 구조로 전환.용어 정의
uploadImagesOnly()로 업로드 선행(TX 밖)@Transactional(REQUIRES_NEW)작업 내용
1) 테스트 픽스처 안정화 (test)
UUID suffix로 생성password필수값 세팅comments / postImages / postLikes / posts엔티티·리포지토리 테스트 전반2) PostImageService 분해 & 유틸 (refactor)
uploadImagesOnly(): S3 업로드 전용(TX 밖 I/O)saveImageUrls(): URL만 DB 반영(짧은 TX)cleanupUploadedOnRollback(): TX 실패 시 업로드분 보상 삭제deleteS3ByUrlsQuietly(): S3 삭제 실패 예외 삼키고 warn 로깅3) createPost — B 구조 적용 (feat/refactor)
uploadImagesOnly) → TX 내post저장 +saveImageUrls4) updatePost — B 구조 적용 (feat/refactor)
mutateImagesAndRefresh일괄 처리흐름:
cleanupUploadedOnRollback등록 →deleteSelectedImagesDbOnly(DB-only, 일부REQUIRES_NEW)→
saveImageUrls→refreshThumbnailIfNeeded(남은 이미지 < 2면 예외)→
applyTextIfChanged(무변경 시 no-op save)5) 트랜잭션 경계/전파 정리
@Transactional을 퍼블릭 엔트리포인트(updatePost)로 이관(기존updatePostTx제거)deleteSelectedImagesDbOnly에@Transactional(REQUIRES_NEW)적용(상위 롤백 영향 최소화)6) 조회/삭제 일관성
getPostById / findByStoreId / findByStoreIdWithCommentsAndLikes→@Transactional(readOnly = true)deleteAllByPost: DB-first → afterCommit S3 정리findFirstImageByPostId제거,findImagesByPostIdreadOnly 지정성능 영향 (B 구조 — 설정 전 vs 설정 후)
A.
PostService.updatePost— B_pre → B_post (각 7회)B.
PostService.createPost— B_pre → B_post (단일 런)테스트 포인트
deleteAllByPostDB-first → afterCommit S3 경로readOnly경계 내 LAZY 접근 정상 동작참고 사항
S3_DELETE_QUIET,POST_IMG_CLEANUP_ON_ROLLBACKJpaTransactionManager시작~커밋 로그 간격관련 이슈