🌱 데이터 충돌
서버에서 트랜잭션을 진행하면 우연이든 필연이든 데이터의 충돌이 일어날 수 있다. 이런 문제를 해결하는 것은 개발자로써 꼭 경험하고 알고 있어야 하는 내용이 아닌가 싶다.
어쨌든 데이터의 일관성이 깨질 수 있기때문에 DB에서 lock을 걸고 관리하는 것을 Locking 이라고 한다
해당 Locking의 방식은 두가지의 방식이 있다.
🌱 낙관적 락(Optimistic)
- 자원에 락을 걸지 않고 데이터 업데이트를 할 때 동시성에 문제가 발생하면 그때 처리하는 것이다.
- 데이터를 수정할때 수정했다고 명시해서 다른 트랜잭션이 동일한 조건으로 값을 수정할 수 없게 하는 것이다.
- 낙관적 락은 동시성이 높은 환경에서 성능을 향상 시킬 수 있지만, 충돌이 발생할 가능성이 높은 경우 롤백이나 재시도가 필요하다
- 충돌이 발생했다면 DB가 아닌 Application Level에서 처리하는 것이다.
관리 방법
Version라는 컬럼을 추가해서 값을 관리한다.
@Entity
public class SampleEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Version
private Long version;
private String data;
}
@Repository
public interface SampleEntityRepository extends JpaRepository<SampleEtity, Long> {
}
@Service
public class SampleEntityService {
@Autowired
private SampleEntityReposiroty sampleEntityRepository;
public SampleEntity updateData(Long id, String newData) {
SampleEntity sampleEntity = sampleEntityRepository.findById(id).orElseThrow();
return sampleEntityRepository.save(sampleEntity);
}
}
- 이렇게 로직을 작성하고 동시에 데이터를 업데이트 한다고 가정하면 version값이 똑같다. 하지만 먼저 도착한 version이 데이터를 처리하게 되면 같은 값을 가진 다른 요청은 실패하지만 예외를 발생시키고 업데이트를 안하고 rollback처리한다.
🌱 비관적 락(Pessimistic)
- 데이터가 충돌되는 것을 당연하게 생각하고 진행하는 방식이다.
- Repeatable Read 또는 Serializable 정도의 격리성 수준을 제공한다
- 데이터를 읽는 순간 부터 락을 걸고 업데이트가 완료될때까지 락을 유지한다
- 락이 바로 걸리기 때문에 다른 트랜잭션이 데이터를 읽거나 수정할 수 없다
- find 메소드에 (LockModeType.PESSIMISTIC_WRITE)을 지정해서 데이터에 락을 걸어둔다.
🌱 어느것이 더 효과적일까
구분 | 낙관적 락 | 비관적 락 |
정의 | 충돌이 없을 것으로 가정하여 락을 걸지 않는다 | 충돌을 예상하고 미리 락을 건다 |
사용법 | JPA 사용시 @Version 동작 원리가 단순해서 Mybatis의 경우 직접 만들어서 사용한다 | Mode 설정 및 쿼리에 직접 사용한다. DB단에서 설정이 가능하다 |
장점 | 데드락 가능성이 적다 | 충돌에 대한 오버헤드가 줄어들며 무결성을 지키기 용이하다 |
단점 | 충돌이 발생하면 오버헤드 발생 | 충돌이 없으면 오버헤드가 발생한다. |
결정 방법
- 충돌 발생 확률이 낮고 성능 저하를 예방하기 위한거라면 낙관적 락
- 충돌을 미연에 방지하고 데이터의 일관성을 유지하려면 비관적 락
선택한 락 방식에 따라 JPA를 효과적으로 사용하여 동시성 처리 이슈를 해결할 수 있다.
'CS > 💾 DB' 카테고리의 다른 글
💾 JOIN이란?? (0) | 2024.05.31 |
---|---|
💾 동시성 문제를 해결하는 방법 (0) | 2024.04.27 |
💾 MVCC, 트랜잭션 ( 5 ) (feat. MySQL과 PostgreSQL 비교) (1) | 2024.04.27 |
💾 LOCK을 활용한 트랜잭션( 4 ) (1) | 2024.04.26 |
💾 Isolation Level, 트랜잭션 ( 3 ) (1) | 2024.04.23 |