@Transactional 복습

검토

예전에 10분 테코톡을 보고 거래 내용을 정리한 적이 있었습니다. 먼저 확인해 봅시다.

첫 번째 트랜잭션은 요청에 대한 작업 단위입니다.생각하기 쉽습니다.

이 트랜잭션이 완료되면 중요한 부분은 내부 연산인데 DB 커넥션 풀을 이용해 커넥션 객체를 얻고 이 객체를 이용해 DB에 요청을 보낸다고 합니다. DB 관점에서 이 연결은 하나의 세션으로 간주되지만 함수의 작업 단위가 연결되지 않으면 결국 다른 연결로 간주되며 세션에서 처리될 때 단일 작업으로 처리됩니다. 따라서 원하는 기대값이 달성되지 않을 가능성이 매우 높습니다.

여기서 핵심은 우리가 만들고자 하는 기능이 궁극적으로 트랜잭션인 작업 단위로 번들되어야 한다는 것입니다.

트랜잭션 관리 방법~ 안에 2가지 방법나는 말했다 선언적 트랜잭션수업 프로그래밍 트랜잭션있다

Declarative는 Annotation의 형태로 문자 그대로 제공되는 것을 의미하고 프로그래밍은 트랜잭션을 직접 관리하는 것을 의미합니다.

직접 프로그래밍을 통해 트랜잭션을 관리하다 보면 중복되는 코드가 많고 주요 관심사가 아닌 코드가 서비스 레이어에 주입된다. 따라서 기능에 필요한 문제에 초점을 맞추지 않고 특정 기술에 특정한 코드나 코드를 작성할 때 문제를 일으킬 수 있습니다.

Spring은 직접 프로그래밍과 같이 복잡하고 번거로운 프록시 객체를 bean에 등록하여 문제를 해결하려고 하는데 이 프록시 객체는 @Transactional이라는 메서드가 포함하고 있다고 가정할 때 PlatformTransactionManager로 트랜잭션을 시작하며 이것이 정상인지 아닌지. 롤백 흐름이 있습니다.

이 트랜잭션에는 많은 성능 문제가 있습니다. 트랜잭션을 열면 계속해서 DB를 깨물어 많은 리소스를 소모하게 됩니다.


더 나아가

본론으로 들어가겠습니다. 트랜잭션이 다시 생성되는 이유는 다음과 같습니다.

트랜잭션을 사용할 때 데이터 작업을 할 때 보통 선언하고 사용하지만 신중하게 사용해야 합니다. 그 이유는 위에서 설명한 것처럼 트랜잭션을 열면 DB가 계속 물고 있는데 이 연결 풀이 제한되어 있기 때문입니다. 그래서 이러한 거래가 계속 물린다면??? 다른 일을 하지 못할 수도 있습니다.

따라서 트랜잭션을 사용하는 경우 필요할 때 사용하는 것을 기억해야 합니다.

여기에서는 일반적으로 데이터를 수신하는 메서드에서 readOnly 트랜잭션 속성을 지정합니다. 이 속성을 지정하면 트랜잭션이 성능상의 이점을 제공하는 읽기 속성으로 적용됩니다. 따라서 이 속성으로 데이터를 삽입, 삭제, 변경하면 런타임 오류가 발생합니다.

이 @Transactional 속성이 ReadOnly로 지정된 경우 성능 이점을 얻기 위해 내부에서 어떻게 작동합니까?

속성 이름만 보면 읽기 전용임을 알 수 있습니다.

엔터티 자체가 지속성 컨텍스트에 의해 관리되면 기본 캐시에서 변경 감지에 많은 이점이 있습니다. 그러나 퍼시스턴스 컨텍스트는 변화 감지를 위한 스냅샷 인스턴스를 유지하기 때문에 메모리를 더 많이 사용하는 단점이 있다.

엔터티가 지속성 컨텍스트에 의해 관리되는 경우 변경 감지를 위한 기본 캐싱의 이점을 얻을 수 없는 이유는 무엇입니까???

예전에는 그 지속성 컨텍스트는 엔터티를 영구적으로 저장하는 환경입니다.오전 . 애플리케이션과 데이터베이스 사이에 객체를 유지하는 것은 논리적인 개념이며 지속성 컨텍스트는 EntityManager를 통해 액세스됩니다. (EntityManager가 생성되면 논리적 개념인 PersistenceContext가 1:1로 생성된다.)

엔터티가 지속성 컨텍스트에 의해 관리되는 경우 개체가 지속성 컨텍스트에 저장되는 지속성 상태입니다. 따라서 영구적으로 만들면 개체가 기본 캐시에 저장되고 그 시점부터 성능상의 이점이 있습니다.

객체를 검색하려면 해당 객체를 찾기 위해 DB에 직접 접속해야 합니다. 그러나 JPA에서는 퍼시스턴스 컨텍스트를 먼저 조회하면 객체를 반환하고 그렇지 않으면 DB에 접근한다. 이 부분은 성능 문제가 가장 먼저 들어오는 부분입니다.

또한 데이터가 즉시 커밋되지 않고 쓰기 지연된 SQL 메모리에 저장되며 커밋되는 순간 데이터 관련 질의문이 발행된다. (삽입)

그리고 변경 감지엔터티 또는 데이터의 변경 사항을 감지합니다. 작동 원리는 다음과 같습니다.

먼저 JPA가 처리되는 시점에서 내부적으로 flush()를 호출하는데, 이때 엔티티의 스냅샷(초기 상태)과 기본 캐시를 비교한다.이에 비해 변경 사항이 있는 경우 업데이트 쿼리는 쓰기 지연된 SQL에 저장되고 커밋되면 flush()를 호출하여 DB에 쿼리를 생성합니다.

마지막으로 지연 로딩이 지연 로딩은 관련 엔터티를 쿼리할 때 프록시(잘못된 개체)를 반환하여 정말 필요할 때 쿼리가 실행되도록 하는 기술입니다. 즉, 원래 조회를 했다면 어떤 조인을 하든 무엇을 하든 한데 모아야 하는데 쿼리문은 해당 데이터를 사용하기 전까지는 보내지 않는다.

트랜잭션 속성을 readOnly로 설정하면 이러한 이점이 있습니다.

요약하면 트랜잭션을 사용하지 않으면 효율적으로 작업할 수 있습니다. 추가하지 않고 서비스 로직을 구성하면 필요할 때 데이터베이스에서 데이터를 요청하는 것이며, 이때 중요한 점은 필요할 때만 요청한다는 것입니다.단, 트랜잭션이 연결되면 해당 서비스 로직이 종료될 때까지 DB를 보유한다. 이러한 차이점과 문제를 알고 있어야 합니다. (필요하면 쓸까요?)

트랜잭션에 readOnly 속성을 부여하지 않고 읽기 전용 엔터티를 얻는 방법이 있습니다.

1. 스칼라 유형별 쿼리

어떻게 생각하나요? 필수 필드를 얻기 위한 엔터티가 아닌 스칼라 타입이지만 엔터티 개체가 아니기 때문에 퍼시스턴스 컨텍스트에서 결과를 관리하지 않는다.

2. 읽기 전용 쿼리 힌트 사용

Hibernate 관련 노트 org.hibernate.readOnly는 읽기 전용 쿼리를 활성화합니다. 그러나 읽기 전용이므로 지속성 컨텍스트는 스냅샷을 저장하지 않으므로 메모리 사용을 최적화할 수 있습니다.

3. 읽기 전용 트랜잭션 사용(readOnly 속성)

이 옵션이 지정되면 Spring Framework는 Hibernate 세션의 플러시 모드를 MANUAL로 설정합니다. 이 때문에 강제로 플러시하지 않으면 플러시가 발생하지 않습니다. 따라서 트랜잭션이 커밋되더라도 퍼시스턴스 컨텍스트가 플러시되지 않아 수정, 삭제, 등록이 되지 않으며, 퍼시스턴스 컨텍스트는 변경 사항을 감지하기 위한 스냅샷을 보관하지 않기 때문에 성능이 향상된다.


참조 페이지:

(JPA) @Transaction(readOnly=true)이 성능을 향상시키는 이유는 무엇입니까?

개요 Spring 프레임워크에서 주석을 사용하여 트랜잭션을 읽기 전용 모드로 만들 수 있습니다. @Transactional(readOnly = true)은 엔터티의 예기치 않은 등록, 수정 및 삭제를 방지하고 성능을 최적화할 수 있습니다.

willseungh0.tistory.com