본문 바로가기
백엔드/JPA

DataSource, Transacation Manager

by 임지혁코딩 2024. 1. 7.

1 DataSource

물리적인 데이터베이스 정보를 담는 인터페이스 .

EmbaddedDataBaseBuilder를 주로 사용함( 구현체) , DataSourceBuilder(jdbc DataSource 사용)

그때 그때 세팅 해주면 된다.

 

2. Transaction Manager

JpaTransactionManager가 기본 spring data jpa 사용 구현체. DataSourceTransactionManager(JDBC DATASOURCE 사용 구현체 )

 

2개 이상의 DBMS설정이 필요할때, 

1. DB를 세팅 2. ENTITYMANAGERFACTORY를 설정해줘야한다. (LOCALCONTAINERENTITYMANAGERFACTORYBEAN) 얘는, 빈으로 @Bean으로 달아주고 구현체를 return 하지 않음.

bean 이후 return을  new LOCALCONTAINERENTITYMANAGERFACTORYBEAN(). 

이유? 해당 bean이 interface말고, 구현체 자체를 bean으로 등록해줘야함 (추가 예외 처리 기능이 있어서)

 

@Transactional (트랜잭션 을 관리한다) 

commit,rollback등을 할 필요가 없다.  jparepoistory의 method에는 이미 붙어 있다. 

test시, datajpatest로 test, @commit,@Rollback을 활용할 수 있다. 

javax transactional이 있는데, 이를 사용하지 않게 주의하자 . springd의 transactional을 쓰자 

 

@Transactional의 다양한 옵션 

1. transactionManager(value) 사용할 트랜잭션 메니저 이름 특정

2. propogation(default : REQUIRED)등이 기본인데, 뭘 하냐면

트랜잭션이 중첩이라면, 어떤 방식으로 동작할지 규칙을 정해줄 필요가 있다. 

3. ISOLATION : 내부 격리 레벨 

4. READONLY :SELECT만 한다. -> 강제성이 있지는 않다

 

PROPOGATION 동작 규칙

1. REQUIRED(기본) : 있으면 보조하고 없으면 새로 만든다 . 2. SUPPORTS : 있으면 보조하고 없으면 트랜잭션 없이

3. MANDATORY 있으면 보조, 없으면 예외 처리 4. REQUIRED_NEW 생성하고 실행, 있던것은 미룸

5.NOT SUPPORTED : 트랜잭션 없이 실행, 있던 것은 미룸 6. NEVER 트랜잭션이 없이 실행, 있으면 예외처리

 

ISOLATION

DEFAULT 데이터베이스에게 맡김 : READ UNCOMMITED -> DIRTY,NONREPEATABLE,PHANTOM 허용

READCOMMITED : NONREPEATDABLE,PHANTOM 허용 . REPETABLE : PHANTOM 

SERIALIZED 완전 직렬 수행 (SQLD 기억하자) 

 

 

embeddeddatabasebuilder를 datasource로 사용함을 명시했다. 

(Data source란, DB와의 관계 커낵션을 담고 있으며 빈으로 등록하여 인자로 넘겨준다. 즉 DB서버와의 연결을 해준다)

JDBC로 쓰고 싶다면, DATASOURCEBUILDER를 써주면 되고.. 이방식을 꼭 기억하자 

 

PROPERTIES의 설정을 받아서 쓰고 싶으면, RETURN을 단순하게 DATASOURCEBUILDER.CREATED().BUILD()만을 해주고 

@CONFIGURATIONPROPERTIES("SPRING-DATASOURCE")로 설정 가능 

 

그럼 이제 LOCALCONTAINERENTITYMANAGERFACTORYBEAN.Datasource를 받아, 이를 기반으로 scan과 adapter등을 추가할 수 있다. 

 

transactionmanager또한 @bean으로 config에서 control. 

 

혹은 이 세가지를 모두 application properties에서 설정할 수도 있다. 

 

**만약에 db가 2개라 datasourcebuilder,entitymanager,transactionmanager 모두가 2개라면? 두개의 db에서 트랜잭션 2개를 보내서 접근할 수 없다. 하나로 트랜잭션을 묶어줘야한다. 기존엔 ChainedTransactionManager를 썼으나 사라졌음. t1안에 t2를 넣어주면, t2가 commit되고 t1이 rollback 되면 문제가 터져서 사라진 것이었다. TransactionSyncronized를 사용하자 . 

 

 

Service layer에서 이렇게 transaction단위를 묶어주면, 메소드별로 트랜잭션이 묶여다고 볼 수 있다. 

 

왜 service layer에서 할까? 비지니스 적인 측면에서 봤을때, 레퍼지토리의 read 이런 것들을 묶어서 service에 사용한다고 생각해보자. 문제가 생겼을때 rollback을 어디까지 해야할까가 트랜잭션의 적용 범위와 이유라고 본다면, service가 비지니스 업무의 단위이기 떄문에 이에 맞추어 service에서 구현하여 많은 레퍼지토리의 기능들을 모두 rollback하는것이 맞다.

event : place가 manytoone관계임을 나타냈다. 

양방향 조회를 위해선 각 table에서 모두 관계차수를 annotation으로 표기해주어야 한다. 

JOINCOLUMN(name = "placeid") 등을 추가하여, 명확하게 어떤 column을 통해 join하는지 표기 한다. 

이때, Tostring을 주의해야한다. 조회가 잘 이루어지지 않는 곳에서 , Tostring.exclude를 진행해줘야한다.

(무한 순환 참조 ) 

place id로 넣는것보다, place자체를 넣는것으로 변경해주는 것이 좋다. 

(optional에 추가 를 원한다면, mappedby()로 변경할 수 있다. 

그렇게 Place 자체를 코드상으로 받는것 처럼 보였다면, placeid는 Event의 field로 없어도 된다. (허나 실제로는 출력하거나 하면 있는것 처럼 나온다)

앞서 말한 반대 예시. Event들을 여러개를 한개의 place에 받을 수 있음을 표현한 것이다. 

mappedby place를 통해 관계의 주인이 누구인지를 표현하면 되는데,

place의 key인 place id를 member가 외래키로 받고 있으므로 mapped by place가 필요하다. 

<Event에 중복된 컬럼이 존재할 수 있으면, list를 쓰자>

 

**!! many to many의 경우에는, 중간 table을 반드시 만들어 줘야 한다. 

'백엔드 > JPA' 카테고리의 다른 글

JPA TEST  (0) 2024.01.07
MYSQL 적용 ++ POSTGRESQL 까지  (0) 2024.01.07
SPRING DATA JPA 실제 활용  (1) 2024.01.07
SPRING DATA JPA 개념들  (0) 2024.01.07