transactional 속성에서 readonly를 왜 걸어줘야 할까?
한번 알아보자.
readOnly 속성이 true로 설정되면, 트랜잭션 내에서 데이터를 변경하는 작업(INSERT, UPDATE, DELETE 등)은 허용되지 않는다. 오직 데이터를 읽는 작업만 수행할 수 있다.
변경 작업을 못하고 읽는작업만 수행하는데 왜 사용해야 하는가?
그 전에 트랜잭션 lock의 개념부터 알아보자
Transaction Lock은 데이터베이스 트랜잭션에서 동시성 제어와 데이터의 일관성 유지를 위해 사용된다. 여러 개의 트랜잭션이 동시에 동일한 데이터에 접근하고 수정하는 경우, 데이터의 무결성을 보장하기 위해 Transaction Lock을 사용한다.
Transaction Lock은 데이터베이스 엔진에서 관리되며, 트랜잭션이 커밋되거나 롤백될 때 자동으로 해제된다.
과도한 Lock의 사용은 성능 저하를 초래할 수 있다. 따라서 Lock의 범위를 적절히 설정하는 것이 중요하다.
Transaction Lock의 종류
공유 락(Shared Lock)
읽기 작업을 수행하는 트랜잭션에서 사용되는 락.
여러 개의 트랜잭션에서 동일한 데이터를 동시에 읽을 수 있지만, 읽기 락이 설정되면 해당 데이터에 대한 수정 작업은 다른 트랜잭션에서 차단된다.
배타적 락(Exclusive Lock)
데이터를 수정하는 작업을 수행하는 트랜잭션에서 사용되는 락.
배타적 락이 설정된 데이터에는 다른 트랜잭션에서의 읽기 또는 쓰기 작업이 차단된다.
배타적 락이 설정된 데이터는 해당 트랜잭션이 커밋 또는 롤백되기 전까지 다른 트랜잭션에서 수정할 수 없다.
데이터를 변경하지 않기 때문에 트랜잭션 충돌이나 롤백에 대한 오버헤드가 없다.
데이터를 읽을 때 트랜잭션 Lock을 사용하지 않으므로 다른 트랜잭션도 동일한 데이터에 대한 읽기 작업을 수행할 수 있다.
master-slave 관계인경우 slave를 통해 조회한다.
데이터의 변경을 하지 않으므로 flush 작업을 수행할 필요가 없다. 따라서 flush 작업을 방지하여 성능을 개선할 수 있다.
명시적으로 읽기만 하는 메서드임을 표시하여 다른 개발자가 보아도 알 수 있다.
데이터 변경 제약: 읽기 전용 트랜잭션에서는 데이터를 변경하는 작업(INSERT, UPDATE, DELETE 등)을 수행할 수 없다. 당연한 소리 아닌가
데이터를 변경하는 작업이 포함되어 있다면, 해당 메서드를 분리하거나 다른 트랜잭션 설정을 사용해야 한다.
데이터베이스 트랜잭션 Lock과 readOnly의 장단점을 알아봤는데, 단점도 사실 단점같지도 않다. 추후에 데이터 변경 작업이 일어날경우 휴먼에러를 초래한다는 점이 있긴 하지만, 그것 외에는 장점만 존재한다고 생각한다.
트랜잭션을 사용하지 않고 그냥 조회하는 경우, 데이터 정합성문제와 지연로딩이 불가능하니 적절히 읽기전용 트랜잭션을 사용하자.
@Transactional이 트래픽 분산도 고려한 설계라는 것은 처음 알았네요!
아래 포스팅을 보니 야믈 파일과 config 파일을 정의해 편리하게 설정할 수 있는 것 같습니다.
https://jangjjolkit.tistory.com/41