Skip to content

[hotfix] #108 - 타이머 종료 불가 에러 해결 - #109

Merged
Jy000n merged 1 commit into
developfrom
feat/#108-timer-stop-error
Jul 13, 2026
Merged

Jy000n merged 1 commit into
developfrom
feat/#108-timer-stop-error

Conversation

@Jy000n

@Jy000n Jy000n commented Jul 13, 2026 •

Copy link
Copy Markdown
Member

관련 이슈 🛠

작업 내용 요약 ✏️

  • 서비스 클래스 단위에 글로벌하게 설정되어 있던 읽기 전용 트랜잭션(readOnly = true)으로 인해, 특정 데이터 변경(CUD) 로직이 DB에 반영되지 않거나 먹통이 되던 버그를 해결했습니다.

주요 변경 사항 🛠️

[버그 수정] 특정 데이터 등록/수정/삭제 로직 트랜잭션 잠금 해제

  • 기존 클래스 레벨의 readOnly = true 잠금을 풀기 위해 기능 메서드 상단에 @Transactional(readOnly = false) 옵션을 추가했습니다.

트러블 슈팅 ⚽️

테스트 결과 📄

스크린샷 📷

리뷰 요구사항 📢

📎 참고 자료 (선택)

Summary by CodeRabbit

  • 버그 수정
    • 타이머 완료 처리 시 변경 사항이 정상적으로 저장되도록 트랜잭션 동작을 개선했습니다.

@Jy000n Jy000n self-assigned this Jul 13, 2026
@Jy000n Jy000n changed the title [hotfix] 타이머 종료 불가 에러 [hotfix] 타이머 종료 불가 에러 해결 Jul 13, 2026
@Jy000n
Jy000n requested a review from aneykrap July 13, 2026 14:47
@Jy000n
Jy000n requested review from aneykrap and laura-jung and removed request for aneykrap July 13, 2026 14:47
@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

Review Change Stack

Walkthrough

TimerService.completeTimer에 메서드 수준 @Transactional(readOnly = false)를 추가해 타이머 종료 시 쓰기 작업이 가능한 트랜잭션을 사용하도록 변경했습니다.

Changes

타이머 완료 처리

Layer / File(s) Summary
완료 메서드 트랜잭션 오버라이드
src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java
completeTimer가 클래스 수준의 읽기 전용 트랜잭션을 덮어쓰고 쓰기 가능한 트랜잭션에서 실행되도록 설정합니다.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Possibly related PRs

  • Team-Timo/Timo-Server#68: completeTimer 및 finishTimer의 타이머 종료 처리와 직접적으로 관련된 변경입니다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed #108의 타이머 종료 시 500 에러 해결 요구를 트랜잭션 readOnly 해제로 직접 충족합니다.
Out of Scope Changes check ✅ Passed 변경 범위가 타이머 종료 관련 트랜잭션 설정 수정에만 한정되어 있어 범위를 벗어난 내용이 보이지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 타이머 종료 시 발생하는 500 에러를 readOnly 트랜잭션 설정 수정으로 해결하는 변경과 잘 일치합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#108-timer-stop-error

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.

@Jy000n Jy000n changed the title [hotfix] 타이머 종료 불가 에러 해결 [hotfix] #108 - 타이머 종료 불가 에러 해결 Jul 13, 2026

@aneykrap aneykrap left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

가자 굳굳

@laura-jung laura-jung left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

트랜잭션의 중요성 잘 보았습니다. 머지합시다

@github-actions github-actions Bot added the slack-approval-notified Slack 승인 완료 알림 중복 방지용 라벨 label Jul 13, 2026
@Jy000n
Jy000n merged commit f58d291 into develop Jul 13, 2026
6 of 7 checks passed

@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 `@src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java`:
- Around line 184-190: Update the completeTimer and stopTimer flow so the
timer-ending state is committed before generateAiFeedback and updateAiFeedback
run. Configure the AI feedback work to execute after the ending transaction in a
separate transaction or commit-after hook, ensuring the findByIdForUpdate lock
is released before any external Gemini call.
🪄 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: 2d70114f-329b-48d7-91c5-7b7c37b20a29

📥 Commits

Reviewing files that changed from the base of the PR and between 4c0ac00 and 518fc26.

📒 Files selected for processing (1)
  • src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java

Comment on lines +184 to 190
@Transactional(readOnly = false)
public TimerFinishResponse completeTimer(Long userId, Long timerId) {
return finishTimer(userId, timerId, TimerStatus.COMPLETED);
}

@Transactional(readOnly = false)
public TimerFinishResponse stopTimer(Long userId, Long timerId) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map and inspect the relevant service files
git ls-files 'src/main/java/com/Timo/Timo/domain/timer/service/*.java' \
  'src/main/java/com/Timo/Timo/domain/*/service/*.java' \
  'src/main/java/com/Timo/Timo/**/TransactionTemplate*.java' \
  'src/main/java/com/Timo/Timo/**/ai*.java' \
  'src/main/java/com/Timo/Timo/**/feedback*.java'

echo '--- TimerService outline ---'
ast-grep outline src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java --view expanded

echo '--- TimerService relevant slice ---'
nl -ba src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java | sed -n '1,320p'

echo '--- Search for generateAiFeedback and TransactionTemplate usage ---'
rg -n "generateAiFeedback|TransactionTemplate|new TransactionTemplate|setPropagationBehavior|PROPAGATION_|createFeedback|aiTodoService" src/main/java/com/Timo/Timo -S

Repository: Team-Timo/Timo-Server

Length of output: 3602


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the specific call chain and transaction boundaries
files=$(git ls-files 'src/main/java/com/Timo/Timo/domain/timer/service/*.java' \
  'src/main/java/com/Timo/Timo/domain/*/service/*.java' \
  'src/main/java/com/Timo/Timo/**/TransactionTemplate*.java' \
  'src/main/java/com/Timo/Timo/**/feedback*.java' \
  'src/main/java/com/Timo/Timo/**/ai*.java' \
  'src/main/java/com/Timo/Timo/**/service/*.java')

printf '%s\n' "$files"

echo '--- TimerService outline ---'
ast-grep outline src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java --view expanded

echo '--- TimerService slice (160-280) ---'
nl -ba src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java | sed -n '160,280p'

echo '--- TimerService full transaction helpers search ---'
rg -n "generateAiFeedback|finishTimerInTransaction|TransactionTemplate|setPropagationBehavior|PROPAGATION_|createFeedback|aiTodoService" src/main/java/com/Timo/Timo -S

Repository: Team-Timo/Timo-Server

Length of output: 3957


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- TimerService 178-280 ---'
sed -n '178,280p' src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java | cat -n

echo '--- AiTodoService ---'
sed -n '1,260p' src/main/java/com/Timo/Timo/domain/ai/service/AiTodoService.java | cat -n

echo '--- GeminiService ---'
sed -n '1,260p' src/main/java/com/Timo/Timo/domain/ai/service/GeminiService.java | cat -n

Repository: Team-Timo/Timo-Server

Length of output: 15399


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- TransactionTemplate / propagation search ---'
rg -n "TransactionTemplate|setPropagationBehavior|PROPAGATION_|`@Transactional`" src/main/java/com/Timo/Timo/domain/ai src/main/java/com/Timo/Timo/domain/timer -S

echo '--- AI history service ---'
sed -n '1,260p' src/main/java/com/Timo/Timo/domain/ai/service/AiTodoHistoryService.java | cat -n

echo '--- AI request limiter ---'
sed -n '1,260p' src/main/java/com/Timo/Timo/domain/ai/service/AiRequestRateLimiter.java | cat -n

Repository: Team-Timo/Timo-Server

Length of output: 7865


AI 호출을 트랜잭션 밖으로 분리하세요.
TransactionTemplate의 기본 전파가 REQUIRED라서, 현재는 completeTimer/stopTimer의 트랜잭션 안에서 generateAiFeedback(...)와 updateAiFeedback(...)가 함께 실행됩니다. findByIdForUpdate로 잡은 락이 외부 Gemini 호출 동안 유지되어 동시성 지연과 타임아웃 위험이 큽니다. 종료 상태는 먼저 커밋하고, AI 피드백 생성/저장은 별도 트랜잭션이나 커밋 이후 훅으로 분리해 주세요.

🤖 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 `@src/main/java/com/Timo/Timo/domain/timer/service/TimerService.java` around
lines 184 - 190, Update the completeTimer and stopTimer flow so the timer-ending
state is committed before generateAiFeedback and updateAiFeedback run. Configure
the AI feedback work to execute after the ending transaction in a separate
transaction or commit-after hook, ensuring the findByIdForUpdate lock is
released before any external Gemini call.

Source: Path instructions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🌸 자윤 🚨 hotfix slack-approval-notified Slack 승인 완료 알림 중복 방지용 라벨

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[hotfix] 타이머 종료(stop) 안 되는 에러 해결

3 participants