DevBoi

[JPA] JPA 트랜잭션 사용 본문

Develop/[JPA]

[JPA] JPA 트랜잭션 사용

HiSmith 2022. 3. 20. 23:52
반응형

스프링 데이터 JPA가 제공하는 Repository의 모든 메소드에는 기본적으로 트랜잭션이 적용되어 있다.

 

클래스,인터페이스,메소드에 사용가능, 메소드에 가장가까운 애노테이션이 우선순위가 높다.

기본적으로 Transactional(readOnly = true) 는 아무런 설정을 하지 않는 메서드에 적용된다.

 

Transcational 옵션

-timeout설정 가능

-readOnly 인지 나타내는 flag 이값을 주면서 optimization 성능 최적화를 해줄 수 있는 여지가 생김

-가급적, 데이터 변경 할 일없으면, readOnly true로 해주는게 좋다.

-> JPA에서 해당 readOnly로하게되면, 세션 플러시 모드가 매뉴얼로 설정이 되고

해당 설정이 되면 강제로 플러시를 하지 않는 이상 플러시를 하지 않게 된다.

-> 이건 트랜잭션을 커밋하여도, 영속성 컨텍스트가 플러시 되지 않게되고 저장이나 값을 변경하는 작업이 일어나지 않게된다.

또한 영속성 컨텍스트에서는 변경을 위한 스냅샷을 별도로 저장하지 않고있게 되어, 성능향상에 도움이 된다.

 

Rollback

RuntimeException이나 에러 발생하면, 해당 트랜잭션을 롤백시킨다.

추가로, checkedException이 발생하면, 롤백시키지 않는데 해당 예외에도 롤백을 원하면, rollbackFor, rollbackForClassName에 설정을 해주면 된다.

또한 RuntimeException이 발생해도 Rollback을 안하려면 noRollbackFor, noRollbackForClassName에 설정 해주면된다.

 

Isolation

트랜잭션이 여러개가 동시에 데이터베이스에 접근했을 때 해당 트랜잭션들을 어떻게 처리할 것인지

동시에 실행되게 할 것인지, 하나씩 차례 대로 접근하게 할 것인지

제어에 대한 설정인데 어떠한 레벨로 주느냐에 따라서 데이터에 동시에 접근했을때 발생할 수 있는 현상이 달라진다.

non repeatable reads, dirty reads,phantom reads등이 있다.

 

격리 종류

-Read uncommited: 어떤 트랜잭션의 변경내용이 commit, rollback과 상관없이 보여진다

장점 : 성능은 가장좋다

단점 : rollback 데이터에 대한 데이터를 볼수있고, 해당 데이터 기준으로 다른 데이터를 처리할 수있다.

 

-Read commited

커밋된 데이터를 읽는 격리 수준

장점 : 기본으로 사용되는 종류,가장 많이 선택되는 격리 수준, 한 트랜잭션 내에서 처리된 데이터를 읽는다

단점 : 한 트랜잭션 내에서, 똑같은 select를 수행했을 경우 항상 같은 결과를 반환해야한다는 repeatable read 정합성에 어긋난다.

 

-Repeatable read

트랜잭션 시작전에, 커밋된 내용에 대해서만 조회할수 있는 격리 수준이다.

자신의 트랜잭션 번호보다 낮은 트랜잭션번호에서 커밋된 데이터만 본다.

시간이 길어질수록 멀티버전을 관리해야하는 단점이 존재하지만, 트랜잭션을 오래 지속하는 경우는 없어서, read commited와 성능 차이는 없다.

 

단점 

update 부정합

update 부정합이 존재할수있다. 특정 조건에 데이터가 변경이 되어야 하는데, 하위 트랜잭션에서 해당 값이 맞춰졌음에도 불구하고

자신의 하위 트랜잭션 이전의 내용만 읽어오기때문에 다른 값으로변경이 안되거나 하는 부정합이 발생한다.

 

Phantom Read

한 트랜잭션 내에서 같은 쿼리를 두번 실행했는데, 첫번쨰 쿼리에서 없던 유령 레코드가 두번째 쿼리에서 나타나는 현상이다.

update 쿼리를 한다고 하면, 해당 영향을 받아, select 쿼리에 유령 데이터가 조회된다.

 

-Serializable

읽기, 쓰기에 대한 공유잠금을 걸고, 동작하는 격리 수준이다. 격리 수준이 다른 수준에 비해 동시처리 능력이 떨어지고

성능 저하가 발생한다.

 

 

Propagation (전파)

 

* propagation.REQUIRED

-default 값이기 떄문에 생략가능

-별도 트랜잭션 설정되어있지 않으면, 트랜잭션을 새로시작

-별도 설정이 되어있으면 기존 트랜잭션 내 로직을 실행 (동일 트랜잭션 안에서 실행된다.)

- 예외 발생시 롤백되고 호출한 곳에서도 롤백이 전파된다.

 

* propagation.Requires_new

-매번 새로운 트랜잭션을 시작

-2개의 트랜잭션이 완전 독립적으로 동작한다.

-새로운 트랜잭션 안에서 롤백은 전파가 되지 않는다

 

* propagation.nested

-부모 트랜잭션에서 진행되는 경우, 별개로 커밋 롤백이 가능하다.

-둘러싼 부모가 없으면 디폴트와 동일하게 작동한다(신규 생성)

-savePoint를 지정한 시점까지 부분 롤백이 가능하다

-DB가 savePoint 기능을 지원해야 사용가능하다.

-진행중인 트랜잭션이 있다면, 중첩 트랜잭션을 시작한다.

 

* propagation support

부모트랜잭션이 존재하면 부모트랜잭션으로 동작하고, 없는 경우, non-transactional하게 동작한다.

 

* propagation. mandatory

부모트랜잭션 내에서 발생하며, 부모 트랜잭션이 없는 경우 Exception이 발생한다.

 

 

 

반응형

'Develop > [JPA]' 카테고리의 다른 글

[JPA] EntityGraph 란  (0) 2022.03.21
[JPA] Open session in view(OSIV)란  (0) 2022.03.21
[JPA]QueryDSL 사용이유, 정의  (0) 2022.03.20
[JPA] ID를 Long으로 하는 이유  (0) 2022.03.20
[JPA] save, saveall의 성능차이  (0) 2022.03.20