스프링부트에서는 트랜잭션이 필요한 서비스 클래스(또는 메소드)에 @Transactional
어노테이션을 달아 간단하게 트랜잭션 설정을 할 수 있다.
transaction
이란📌 트랜잭션은 데이터베이스의 상태를 변경시키는 작업 또는 한번에 수행되어야하는 연산들을 의미한다.
이 때, '데이터베이스의 상태를 변화시킨다'는 것은 SQL
을 이용하여 데이터베이스에 접근하는 것을 말한다.
트랜잭션 작업이 끝나면 commit
또는 rollback
되어야한다.
transaction
의 성질원자성 : 한 트랜잭션 내에서 실행한 작업들은 모두 성공 or 모두 실패
일관성 : 트랜잭션은 일관성있는 데이터베이스 상태를 유지한다.
격리성 : 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 격리해야한다.
영속성 : 트랜잭션이 성공적으로 처리되면 결과가 항상 저장되어야한다.
📌 트랜잭션을 사용하는 이유는 데이터의 일관성을 유지하면서 안정적으로 데이터를 복구하기 위함이다.
transaction
상태Commit
: 모든 작업들을 정상적으로 처리하겠다고 확정하는 명령어. DB에 영구 저장
Rollback
: 변경사항을 취소. 트랜잭션이 시작되기 이전의 상태로 되돌린다. 즉, 마지막 Commit을 완료한 시점으로 다시 돌아간다.
프로젝트를 진행하면서 테이블을 OneToMany로 조인하였는데 One의 id가 Many테이블의 id값으로 들어가지 않았다.
컬럼은 생겼는데 값이 계속 null이었고, 나는 모델 클래스의 문제인 줄 알고 계속 헛다리를 짚었다.
하루를 통째로 이 문제 때문에 고생했는데 원인은 아주 사소하고 생각지도 못한 것이었다. 바로 로직을 수행하는 메서드에 @Transactional
을 붙여주지 않았던 것이다.
그동안에는 update를 수행하는 메서드에만 붙여주었기에 이런 일이 벌어진 것 같다.
📌 앞으로는 service 클래스 자체에 어노테이션을 붙여주던지, DB의 상태/데이터를 변경시키는 모든 메서드에 잊지 않고 어노테이션을 붙여주자.