•
TransacitonInterceptoor
◦
invokeWithinTransaction
•
TAS
◦
createTransactionIfNecessary
◦
tm.getTransaction
•
APTM
◦
startTransaction
◦
doBegin
•
JTM
◦
getJpaDialect().beginTransaction
•
AJD
◦
entityManager.getTransaction().begin
•
TI(TransactionImpl)
◦
this.transactionDriverControl.begin
•
LCMI(LogicalConnectionManagedImpl)
◦
getConnectionForTransactionManagement
◦
getPhysicalConnection
◦
acquireConnectionIfNeeded
◦
jdbcConnectionAccess.obtainConnection
•
HikariDataSource
◦
getConnection
service 에 transactional 이 없을 시
repository 호출하면 connection 획득
2번 호출하면 둘 다 커넥션이 다름 근데 같음
hikari proxy connection 은 다른데 결국 jdbc connection 은 같음!
있으면 hikari proxy connection 까지 같다! 왜냐믄 이미 service 메서드 호출 전에 커넥션을 획득하거든!
→ 아마 hikari proxy connection 은 논리적 커넥션, jdbc connection 은 물리적 커넥션
1.
트랜잭션 동기화
a.
데이터 접근 기술과 트랜잭션 서비스 사이 종속성 제거
b.
DataSourceUtils.getConnection(dataSource);
c.
후에 실제 쿼리 메서드 실행 시 받아온 동기화 매니저에 있는 connection 이용
d.
여러 쿼리 메서드 실행 시 원래는 각 메서드마다 받아온 connection을 파라미터로 넣어서 같은 connection 임을 보장해야 했는데 트랜잭션 동기화 매니저로 파라미터로 넣을 필요 없이 connection 을 같게 보장 가능하다!
2.
트랜잭션 추상화
a.
get transaction 을 용이하게
b.
jdbc, jpa, hibernate 이 모두 트랜잭션을 얻어오는 방식이 다르다.
c.
플랫폼 트랜잭션 매니저로 추상화!
1.
CrudMethodMetadataPopulatingMethodInterceptor 에서 TransactionSynchronizationManager.getResource(method); 호출
근데 처음이면 null 이라 bindResource() 호출
2.
TransactionInterceptor → PlatformTransactionManager(getTransaction()) → TSM(getResource) 순으로 호출
3.
transaction 이 없으니까 PTM(startTransaction()) 호출, connection 시작!
init 할 때 Pool 에서 JdbcConnection 을 생성한다. async 로 도는 것 같다,,
init 할 때 계속 connection 부른 이유!
→ select name, value from information_schema.settions where name in (?, ?, ?, ?); 세팅 확인하려고!
→ schema, data scripts 넣기 위해!
Transaction 이 다르면 connection 이 다르다!
→ 반은 맞고 반은 틀리다.
connection 이 반환이 이미 되었으면 또 똑같은 connection 을 사용한다.
// @Transactional - service 메서드에 traction 없는 상태
public void test() {
memberRepository.save(); // connection 쓰고 반환
memberRepository.save(); // 위와 똑같은 connection 쓰고 반환
}
Java
복사
이게 connection pool 이 list 로 되어있긴 함. 그래서 그런건지 connection 가져오는 시점을 확인해보자
아니면 똑같은 쓰레드라서 그럴지도?
새로운 Transaction 이면 다른 connection 을 사용한다.
@Transactional
public void test() {
memberRepository.save();
anotherService.test2();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void test2() {};
Java
복사
아직 test() 에서 connection 이 반환되지 않은 상태, REQUIRES_NEW 로 새로운 트랜잭션을 열면 connection 이 다르다.