Skip to content

거래요청_중복_생성_방지_및_조회_성능_개선 : fix : 인덱스 관련 마이그레이션 및 테스트 완료 #808 - #810

Merged
discipline24 merged 4 commits into
mainfrom
20260729_#808_거래요청_중복_생성_방지_및_조회_성능_개선
Jul 30, 2026

Hidden character warning

The head ref may contain hidden characters: "20260729_#808_\uac70\ub798\uc694\uccad_\uc911\ubcf5_\uc0dd\uc131_\ubc29\uc9c0_\ubc0f_\uc870\ud68c_\uc131\ub2a5_\uac1c\uc120"
Merged

discipline24 merged 4 commits into
mainfrom
20260729_#808_거래요청_중복_생성_방지_및_조회_성능_개선

Conversation

@discipline24

@discipline24 discipline24 commented Jul 29, 2026 •

Copy link
Copy Markdown
Collaborator
  • 활성 거래 요청 물품쌍 기준 partial unique index 추가
  • take/give item 조회 패턴에 맞춘 partial composite index 추가
  • 중복 거래 요청 조회 쿼리를 인덱스 활용 가능한 native EXISTS 쿼리로 개선
  • 동시 중복 insert 발생 시 DataIntegrityViolationException을 도메인 예외로 변환
  • PostgreSQL 목데이터 기반 동시성 테스트 및 인덱스 전후 성능 테스트 추가
  • 테스트 실행 시 콘솔에서 동시성 결과와 ms 단위 성능 비교 로그 출력

Summary by CodeRabbit

  • 버그 수정
    • 활성 상태 기준 동일 물품쌍 중복 거래 요청 판별을 더 정확하게 개선했습니다(물품 방향 무관, 취소 상태는 재요청 차단 제외).
    • 거래 요청 저장 중 동시성 중복으로 인한 무결성 예외를 일관되게 처리하고 경고 로그를 보강했습니다.
  • 성능 개선
    • 활성 물품쌍 중복에 대한 인덱스/정규화 기준을 강화하고, 마이그레이션 시 조건 불충족이면 중단되도록 변경했습니다.
  • 테스트
    • PostgreSQL 인덱스 활용 및 성능 계획 검증을 더 세밀하게 조정하고, 실행 중 예외 상황에서도 안정적으로 종료되게 개선했습니다.
  • 빌드
    • 인덱스 관련 테스트 실행 조건 및 로깅 노출을 프로퍼티/환경변수 기반으로 정교화했습니다.

- 활성 거래 요청 물품쌍 기준 partial unique index 추가
- take/give item 조회 패턴에 맞춘 partial composite index 추가
- 중복 거래 요청 조회 쿼리를 인덱스 활용 가능한 native EXISTS 쿼리로 개선
- 동시 중복 insert 발생 시 DataIntegrityViolationException을 도메인 예외로 변환
- PostgreSQL 목데이터 기반 동시성 테스트 및 인덱스 전후 성능 테스트 추가
- 테스트 실행 시 콘솔에서 동시성 결과와 ms 단위 성능 비교 로그 출력
@coderabbitai

coderabbitai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

Review Change Stack

Walkthrough

활성 물품쌍 조회를 PostgreSQL EXISTS 쿼리로 변경하고, 동시 저장 무결성 예외를 도메인 예외로 변환합니다. 중복 데이터가 있으면 인덱스 마이그레이션을 중단하며, PostgreSQL 실행 계획 검증과 테스트 실행 설정을 조정합니다.

Changes

거래 요청 중복 방지

Layer / File(s) Summary
활성 물품쌍 조회와 저장 제약
RomRom-Domain-Item/src/main/java/com/romrom/item/repository/postgres/TradeRequestHistoryRepository.java, RomRom-Domain-Item/src/main/java/com/romrom/item/service/TradeRequestService.java, RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql
SELECT EXISTS와 LEAST/GREATEST로 활성 물품쌍을 조회하고, 저장 중 DataIntegrityViolationException을 ALREADY_REQUESTED_ITEM으로 변환합니다. 활성 물품쌍 중복 발견 시 마이그레이션을 예외로 중단합니다.
PostgreSQL 실행 계획 검증과 테스트 실행
RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java, build.gradle
동시성 테스트의 리소스 정리를 보장하고, 대상 테이블별 순차 스캔과 제한 조회 인덱스 사용을 검증하도록 단정을 조정합니다. PostgreSQL 인덱스 테스트 프로퍼티 전달과 로깅 설정을 추가합니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ConcurrentRequests
  participant TradeRequestService
  participant PostgreSQL
  ConcurrentRequests->>TradeRequestService: 동일 물품쌍 거래 요청 제출
  TradeRequestService->>PostgreSQL: 거래 요청 저장 및 flush
  PostgreSQL-->>TradeRequestService: 저장 성공 또는 무결성 충돌
  TradeRequestService-->>ConcurrentRequests: 성공 또는 ALREADY_REQUESTED_ITEM 반환
Loading

Possibly related issues

  • 이슈 808: 정규화된 중복 검사, 인덱스 생성, 동시성 예외 처리를 다루는 변경과 직접 연결됩니다.

Possibly related PRs

  • TEAM-ROMROM/RomRom-BE#453: TradeRequestHistoryRepository와 TradeRequestService의 거래 요청 상태 및 물품 매칭 로직 변경과 직접 연결됩니다.
  • TEAM-ROMROM/RomRom-BE#456: existsTradeRequestBetweenItems 도입과 아이템 ID 기반 호출 흐름이 현재 쿼리 변경과 직접 연결됩니다.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 거래요청 중복 생성 방지와 조회 성능 개선이라는 핵심 변경을 잘 반영한 제목입니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 20260729_#808_거래요청_중복_생성_방지_및_조회_성능_개선

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (7)
RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql (2)

66-88: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

created_date 컬럼 존재 여부는 확인하지 않습니다.

앞의 가드는 take_item_item_id, give_item_item_id, trade_status만 검사하는데 두 조회 인덱스는 created_date를 포함합니다. 컬럼 방어 로직의 일관성을 위해 함께 확인하는 편이 좋습니다.

🛡️ 제안 수정
     ) AND EXISTS (
         SELECT 1
         FROM information_schema.columns
         WHERE table_schema = 'public'
           AND table_name = 'trade_request_history'
           AND column_name = 'trade_status'
+    ) AND EXISTS (
+        SELECT 1
+        FROM information_schema.columns
+        WHERE table_schema = 'public'
+          AND table_name = 'trade_request_history'
+          AND column_name = 'created_date'
     ) THEN
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql`
around lines 66 - 88, Update the guards for idx_trh_take_active_created_date and
idx_trh_give_active_created_date to also verify that the created_date column
exists before attempting either CREATE INDEX, while preserving the existing
checks for take_item_item_id, give_item_item_id, and trade_status.

57-86: 🚀 Performance & Scalability | 🔵 Trivial

운영 DB 규모에 따라 인덱스 생성 시 쓰기 차단 시간을 고려하세요.

CREATE INDEX(비 CONCURRENTLY)는 대상 테이블에 대해 INSERT/UPDATE/DELETE를 인덱스 빌드 종료까지 막습니다. trade_request_history 행 수가 큰 환경이라면 서비스 영향이 발생할 수 있습니다. CREATE INDEX CONCURRENTLY는 트랜잭션 블록(즉 DO 블록/Flyway 기본 트랜잭션) 안에서 실행할 수 없으므로, 필요하다면 해당 마이그레이션만 PostgreSQL용 non-transactional 실행으로 분리하고 pg_index.indisvalid 검증을 후속 단계로 두는 방식을 검토해 볼 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql`
around lines 57 - 86, Update the index creation flow for
uq_trh_active_item_pair, idx_trh_take_active_created_date, and
idx_trh_give_active_created_date to avoid blocking writes on large
trade_request_history tables: move these CREATE INDEX operations out of the DO
block and configure the migration as PostgreSQL non-transactional so they can
use CREATE INDEX CONCURRENTLY. Add a follow-up validation step that checks
pg_index.indisvalid before treating each index as ready.
RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java (2)

65-88: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

단정 실패 시 스레드 풀이 정리되지 않습니다.

Line 78이나 Line 83의 단정/타임아웃이 실패하면 shutdown()에 도달하지 못해 32개 스레드와 커넥션이 남습니다. try/finally 또는 try-with-resources 대상으로 감싸 주세요.

♻️ 제안 리팩터링
     ExecutorService executorService = Executors.newFixedThreadPool(CONCURRENT_REQUESTS);
+    int successCount = 0;
+    try {
       ...
-    int successCount = 0;
-    for (Future<Boolean> future : futures) {
-      if (future.get(10, TimeUnit.SECONDS)) {
-        successCount++;
-      }
-    }
-    executorService.shutdown();
-    assertThat(executorService.awaitTermination(10, TimeUnit.SECONDS)).isTrue();
+      for (Future<Boolean> future : futures) {
+        if (future.get(10, TimeUnit.SECONDS)) {
+          successCount++;
+        }
+      }
+    } finally {
+      executorService.shutdownNow();
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java`
around lines 65 - 88, Ensure the concurrent execution block in
TradeRequestHistoryPostgresIndexTest always cleans up executorService when
readyLatch.await, future.get, or awaitTermination assertions fail. Wrap the
submission, waiting, result collection, and termination assertions in
try/finally, invoking shutdown in the cleanup path while preserving the existing
timeout and success-count behavior.

162-163: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

벽시계 시간 비교 단정은 플레이키합니다.

인덱스 적용 후 평균이 항상 더 낮다고 단정하면 CI 부하나 캐시 상태에 따라 간헐적으로 실패합니다. 또한 측정값이 0.0이면 Line 661/689의 개선 배수 계산이 Infinity가 됩니다. EXPLAIN (FORMAT JSON) 결과에서 Index Scan/Index Only Scan 사용 여부를 검증하는 결정적 단정으로 바꾸고, 시간 비교는 로그/리포트 참고값으로 남기는 편이 안정적입니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java`
around lines 162 - 163, Update TradeRequestHistoryPostgresIndexTest so the
assertions no longer require indexedResult.activePairLookupAverageMs() or
receivedListAverageMs() to be lower than the no-index timings. Validate
deterministic Index Scan or Index Only Scan usage from the EXPLAIN (FORMAT JSON)
results instead, while retaining timing values only as diagnostic report/log
data and guarding improvement-ratio calculations against zero measurements.
RomRom-Domain-Item/src/main/java/com/romrom/item/service/TradeRequestService.java (1)

93-99: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

DataIntegrityViolationException을 전부 중복 요청으로 단정하면 원인이 가려집니다.

saveAndFlush 시 발생하는 무결성 위반은 uq_trh_active_item_pair 충돌뿐 아니라 FK 위반이나 trade_request_history_item_trade_options 삽입 실패 등에서도 나올 수 있습니다. 제약명으로 판별하고, 그 외에는 원본 예외를 전파(또는 원인 로깅)하는 편이 장애 분석에 유리합니다.

♻️ 제안 리팩터링
     try {
       tradeRequestHistoryRepository.saveAndFlush(tradeRequestHistory);
     } catch (DataIntegrityViolationException e) {
+      String constraintName = e.getMostSpecificCause().getMessage();
+      if (constraintName == null || !constraintName.contains("uq_trh_active_item_pair")) {
+        log.error("거래 요청 저장 중 무결성 위반: takeItemId={}, giveItemId={}",
+            takeItem.getItemId(), giveItem.getItemId(), e);
+        throw e;
+      }
       log.warn("동시 거래 요청 중복 저장 시도 차단: takeItemId={}, giveItemId={}",
           takeItem.getItemId(), giveItem.getItemId());
       throw new CustomException(ErrorCode.ALREADY_REQUESTED_ITEM);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@RomRom-Domain-Item/src/main/java/com/romrom/item/service/TradeRequestService.java`
around lines 93 - 99, Update the saveAndFlush error handling in the trade
request service to convert only violations of the uq_trh_active_item_pair
constraint into ALREADY_REQUESTED_ITEM. For other
DataIntegrityViolationException causes, preserve and propagate the original
exception (and its details) instead of treating them as duplicate requests.
RomRom-Domain-Item/src/main/java/com/romrom/item/repository/postgres/TradeRequestHistoryRepository.java (1)

22-33: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

trade_status ordinal 하드코딩은 enum 순서 변경에 무방비합니다.

같은 인터페이스의 다른 쿼리는 모두 com.romrom.common.constant.TradeStatus.X 상수를 참조하는데, 이 native 쿼리와 마이그레이션의 partial index만 0, 1, 3, 4 리터럴에 의존합니다. TradeStatus에 상태를 중간 삽입하거나 순서를 바꾸면 쿼리와 유니크 인덱스가 동시에 조용히 잘못된 집합을 가리키게 됩니다. 최소한 @EnumType/ordinal 계약을 고정하는 단정 테스트(예: TradeStatus.PENDING.ordinal() == 0 …)를 추가하거나, 주석으로 마이그레이션 파일과의 동기화 의무를 명시해 두는 편을 권합니다.

참고로 native 쿼리는 JPQL과 달리 Hibernate auto-flush 대상이 아니므로, 향후 같은 트랜잭션에서 저장 후 이 메서드를 재호출하는 흐름이 생기면 미flush 데이터가 보이지 않습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@RomRom-Domain-Item/src/main/java/com/romrom/item/repository/postgres/TradeRequestHistoryRepository.java`
around lines 22 - 33, Add a focused test for TradeStatus that asserts the
ordinal values used by existsTradeRequestBetweenItems remain PENDING=0 and the
other referenced statuses remain 1, 3, and 4, preserving the native query and
partial-index contract. Alternatively, document this ordinal synchronization
requirement near the repository method and migration; do not change unrelated
flush behavior.
build.gradle (1)

67-78: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

빌드 스크립트를 연산자가 줄 끝에 있는 형태로 유지하세요.

이 표현식은 현재 || 'true'.equalsIgnoreCase(...) || ...가 괄호 안에서 이어지고 있어 파싱 자체는 위험하지 않습니다. 다만 Groovy build.gradle의 일반 규칙은 연산자를 앞 줄 끝에 놓는 것이니, 필요 시 아래처럼 연산자 위치만 통일하세요.

🔧 제안 수정
-            def runsPostgresIndexTest = filter.getCommandLineIncludePatterns().any {
-                it.contains('TradeRequestHistoryPostgresIndexTest')
-            } || 'true'.equalsIgnoreCase(System.getProperty('romrom.postgres.index-test.enabled'))
-                    || 'true'.equalsIgnoreCase(System.getenv('ROMROM_POSTGRES_INDEX_TEST_ENABLED'))
+            def runsPostgresIndexTest = filter.getCommandLineIncludePatterns().any {
+                it.contains('TradeRequestHistoryPostgresIndexTest')
+            } &&
+                    'true'.equalsIgnoreCase(System.getProperty('romrom.postgres.index-test.enabled')) &&
+                    'true'.equalsIgnoreCase(System.getenv('ROMROM_POSTGRES_INDEX_TEST_ENABLED'))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build.gradle` around lines 67 - 78, Update the runsPostgresIndexTest
expression in the doFirst block so each continuation line places the || operator
at the end of the preceding line, while preserving the existing conditions and
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql`:
- Around line 4-49: Wrap the full migration logic in the existing DO block with
an EXCEPTION WHEN OTHERS handler that issues RAISE WARNING and prevents errors
from propagating to Flyway. Change the duplicate_active_pair_count branch from
RAISE EXCEPTION to a warning and skip index creation when duplicates exist,
while preserving normal index creation when validation succeeds.

In
`@RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java`:
- Around line 128-157: Update the performance test around
dropActualMigrationIndexes, seedActualPerformanceRows, and measurePerformance so
it runs against an isolated database instance or dedicated schema rather than
shared production tables. Keep the index-removal, seeding, measurement, and
rollback flow intact within that isolated environment, ensuring
uq_trh_active_item_pair and other operational indexes are never removed from
shared tables.
- Around line 594-601: Update the connect() method and its propertyOrEnv calls
to remove hardcoded PostgreSQL URL, username, and password fallbacks. Require
each connection setting to be explicitly configured and fail clearly (or skip
the destructive test) when any is missing, preventing accidental access to a
local database.

---

Nitpick comments:
In `@build.gradle`:
- Around line 67-78: Update the runsPostgresIndexTest expression in the doFirst
block so each continuation line places the || operator at the end of the
preceding line, while preserving the existing conditions and behavior.

In
`@RomRom-Domain-Item/src/main/java/com/romrom/item/repository/postgres/TradeRequestHistoryRepository.java`:
- Around line 22-33: Add a focused test for TradeStatus that asserts the ordinal
values used by existsTradeRequestBetweenItems remain PENDING=0 and the other
referenced statuses remain 1, 3, and 4, preserving the native query and
partial-index contract. Alternatively, document this ordinal synchronization
requirement near the repository method and migration; do not change unrelated
flush behavior.

In
`@RomRom-Domain-Item/src/main/java/com/romrom/item/service/TradeRequestService.java`:
- Around line 93-99: Update the saveAndFlush error handling in the trade request
service to convert only violations of the uq_trh_active_item_pair constraint
into ALREADY_REQUESTED_ITEM. For other DataIntegrityViolationException causes,
preserve and propagate the original exception (and its details) instead of
treating them as duplicate requests.

In
`@RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql`:
- Around line 66-88: Update the guards for idx_trh_take_active_created_date and
idx_trh_give_active_created_date to also verify that the created_date column
exists before attempting either CREATE INDEX, while preserving the existing
checks for take_item_item_id, give_item_item_id, and trade_status.
- Around line 57-86: Update the index creation flow for uq_trh_active_item_pair,
idx_trh_take_active_created_date, and idx_trh_give_active_created_date to avoid
blocking writes on large trade_request_history tables: move these CREATE INDEX
operations out of the DO block and configure the migration as PostgreSQL
non-transactional so they can use CREATE INDEX CONCURRENTLY. Add a follow-up
validation step that checks pg_index.indisvalid before treating each index as
ready.

In
`@RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java`:
- Around line 65-88: Ensure the concurrent execution block in
TradeRequestHistoryPostgresIndexTest always cleans up executorService when
readyLatch.await, future.get, or awaitTermination assertions fail. Wrap the
submission, waiting, result collection, and termination assertions in
try/finally, invoking shutdown in the cleanup path while preserving the existing
timeout and success-count behavior.
- Around line 162-163: Update TradeRequestHistoryPostgresIndexTest so the
assertions no longer require indexedResult.activePairLookupAverageMs() or
receivedListAverageMs() to be lower than the no-index timings. Validate
deterministic Index Scan or Index Only Scan usage from the EXPLAIN (FORMAT JSON)
results instead, while retaining timing values only as diagnostic report/log
data and guarding improvement-ratio calculations against zero measurements.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 67411769-413d-4932-b080-beab61b94a90

📥 Commits

Reviewing files that changed from the base of the PR and between 0a155a7 and e4d65f6.

📒 Files selected for processing (5)
  • RomRom-Domain-Item/src/main/java/com/romrom/item/repository/postgres/TradeRequestHistoryRepository.java
  • RomRom-Domain-Item/src/main/java/com/romrom/item/service/TradeRequestService.java
  • RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql
  • RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java
  • build.gradle

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java (1)

75-85: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

실패 경로에서도 워커 스레드를 반드시 종료하세요.

Line 75의 대기가 실패하면 startLatch가 열리지 않고 32개 워커가 계속 대기합니다. 이후 executor 종료도 건너뛰어 테스트 JVM이 멈출 수 있습니다. 전체 실행 구간을 try/finally로 감싸고 finally에서 latch를 해제한 뒤 shutdownNow() 하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java`
around lines 75 - 85, Wrap the concurrent test execution around
startLatch.countDown(), future collection, and executor termination in a
try/finally block. In finally, always release startLatch and call
executorService.shutdownNow() so workers are stopped even when await or
future.get fails; preserve the existing success-count and normal termination
assertions on the successful path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java`:
- Around line 162-166: Remove the strict wall-clock performance assertions in
TradeRequestHistoryPostgresIndexTest, including the comparisons against
noIndexResult. Keep these measurements available for logging or diagnostics, and
validate index usage through EXPLAIN or a separate controlled benchmark rather
than requiring every indexed timing to be lower.

---

Outside diff comments:
In
`@RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java`:
- Around line 75-85: Wrap the concurrent test execution around
startLatch.countDown(), future collection, and executor termination in a
try/finally block. In finally, always release startLatch and call
executorService.shutdownNow() so workers are stopped even when await or
future.get fails; preserve the existing success-count and normal termination
assertions on the successful path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6189f9ad-a5d9-4c0f-988b-b01ec68b6051

📥 Commits

Reviewing files that changed from the base of the PR and between e4d65f6 and c78dfff.

📒 Files selected for processing (1)
  • RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java



- 거래요청 활성 물품쌍 중복 방지를 위한 partial unique index 마이그레이션 보강
- Flyway 마이그레이션에 예외 핸들러 추가 및 중복 데이터 존재 시 warning 후 unique index 생성 스킵
- PostgreSQL 성능 테스트를 public 테이블 직접 조작 방식에서 격리 스키마 기반으로 변경
- 테스트 DB 접속정보 기본값 제거 및 명시적 설정 없을 시 실패하도록 수정
- 성능 시간 비교 assert 제거, EXPLAIN ANALYZE 기반 대상 인덱스 사용 여부 검증으로 테스트 안정화
- LIMIT 20 / LIMIT 없음 기준 받은·보낸 거래요청 목록 조회 성능 로그 출력

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql`:
- Around line 48-52: V1_4_66__add_trade_request_history_active_pair_indexes.sql의
중복 분기에서는 경고만 남기고 종료하지 말고, 중복 정리 후 유니크 인덱스 생성을 보장하는 별도 repair migration을 추가하세요.
같은 파일의 예외 처리 블록은 예상 가능한 오류만 처리하고, 그 외 오류는 전파하거나 재시도 경로로 추적되도록 수정하세요.

In
`@RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java`:
- Around line 65-88: TradeRequestHistoryPostgresIndexTest의 동시 실행 구간에서 assertion
또는 future 대기 실패 시 executor와 워커가 정리되지 않습니다. readyLatch 대기와 futures 처리 로직을
try/finally로 감싸고, finally에서 startLatch.countDown()으로 대기 중인 작업을 깨운 뒤
executorService.shutdownNow() 또는 기존 정리 정책에 맞는 종료를 수행하고 awaitTermination으로 종료를
확인하세요.
- Around line 784-797: Adjust the assertions in
assertNoTradeRequestHistoryIndexUsed and assertTargetIndexesUsed: scope the
sequential-scan check to the trade_request_history table rather than accepting
any “Seq Scan,” retain index assertions only for the LIMIT query plans
receivedListLimit and sentListLimit, and replace the no-LIMIT index assertions
with plan logging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ecdd8313-ce13-45f9-8181-0c39ccde4a32

📥 Commits

Reviewing files that changed from the base of the PR and between c78dfff and a2d1cdd.

📒 Files selected for processing (2)
  • RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql
  • RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java

- 활성 거래요청 중복 물품쌍 존재 시 마이그레이션 실패 처리
- Postgres 성능/동시성 테스트 executor 정리 로직 보강
- EXPLAIN 검증 범위를 trade_request_history 및 LIMIT 조회 중심으로 조정

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql`:
- Around line 49-52: Update the DO block containing duplicate_active_pair_count
so the duplicate-data RAISE EXCEPTION uses a distinct SQLSTATE and is explicitly
re-raised, while the generic EXCEPTION WHEN OTHERS handler follows the project’s
RAISE WARNING convention. Preserve migration failure for duplicate active pairs
and ensure unrelated exceptions are handled by the standard warning path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 93449028-71c5-41fd-bf71-1f09a85eb4a3

📥 Commits

Reviewing files that changed from the base of the PR and between a2d1cdd and a0cfd26.

📒 Files selected for processing (2)
  • RomRom-Web/src/main/resources/db/migration/V1_4_66__add_trade_request_history_active_pair_indexes.sql
  • RomRom-Web/src/test/java/com/romrom/web/performance/TradeRequestHistoryPostgresIndexTest.java

@discipline24
discipline24 merged commit c6f6720 into main Jul 30, 2026
1 check passed
@discipline24
discipline24 deleted the 20260729_#808_거래요청_중복_생성_방지_및_조회_성능_개선 branch July 30, 2026 03:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 [기능개선][거래요청] 거래요청 중복 생성 방지 및 조회 성능 개선

1 participant