
jakarta.servlet.ServletException: Request processing failed: org.springframework.orm.jpa.JpaSystemException: could not execute statement [Connection is read-only. Queries leading to data modification are not allowed] [insert into todos (contents,created_at,modified_at,title,user_id,weather) values (?,?,?,?,?,?)]
원인은 todo의 service 클래스

TodoService 클래스에서 해당 메서드에 @Transactional 이 없거나, 클래스 전체에 @Transactional(readOnly = true)가 선언되어 있기 때문.
🤔@Transactional(readOnly = true)가 왜 문제를 일으키는가?
@Transactional(readOnly = true)는 말 그대로 읽기 전용 트랜잭션을 의미한다.데이터베이스 연결이 읽기 전용 모드로 설정된다.
INSERT, UPDATE, DELETE와 같은 데이터 변경 작업이 허용되지 않는다.
에러 메시지에서 보이는 "Connection is read-only. Queries leading to data modification are not allowed"는
-> 읽기 전용 연결에서 데이터 수정 쿼리(INSERT)를 실행할 수 없다는 것을 의미
메서드 레벨에 별도로 @Transactional 어노테이션을 추가하면 클래스 레벨 설정을 오버라이드 해야 한다.
public TodoSaveResponse saveTodo(AuthUser authUser, TodoSaveRequest todoSaveRequest)
따라서, 트랜잭션을 효율적으로 관리하기 위한 권장 사항은 다음과 같다:
- 클래스 레벨에
@Transactional(readOnly = true)를 선언하여 기본적으로 모든 메서드를 읽기 전용으로 설정
- 데이터 수정이 필요한 메서드(CREATE, UPDATE, DELETE)에만
@Transactional을 선언하여 오버라이드
- 이렇게 하면 읽기 작업의 경우 성능 최적화를 유지하면서 필요한 곳에서만 데이터 수정이 가능
이런 방식으로 트랜잭션을 관리하면 성능 최적화와 데이터 무결성을 모두 달성할 수 있다.