11/14 GDSC 백엔드 스터디 정리
목차
1. ORM
2. JPA
3. 트랜잭션
ORM
ORM
Object - relational mapping(객체 관계 매핑)
객체는 객제대로 설계
관계형 데이터베이스는 관계형 데이터베이스대로 설계
ORM 프레임워크가 중간에서 매핑
대중적인 언어에는 대부분 ORM 기술이 존재
ORM의 등장 동기
데이터베이스를 사용함에 있어 기본적으로 SQL에 의존적인 개발을 피하기 어렵다.
사실상 개발자 == SQL 매퍼
객체지향 프로그래밍의 장점
객체지향 프로그래밍은 추상화, 캡슐화, 정보 은닉, 상속, 다형성 등 시스템의 복잡성을 제어할 수 있는 다양한 장치들을 제공한다.
ORM이 없을 시
상속의 경우
- 1. 객체 분해
- 2. INSERT INTO ITEM ...
- 3.INSERT INTO ALBUM ...
- 4. 각각의 테이블에 따른 조인 SQL 작성...
- 5. 각각의 객체 생성...
- 상상만 해도 복잡
- 그래서 데이터베이스에 저장할 객체에는 상속 관계 안 쓴다.
자바를 활용한다면?
list.add(album);
Album album = list.get(albumId);
부모 타임으로 조회 후 다형성 활용
Item item = list.get(albumId);
연관 관계
- 객체는 참조를 사욜: member.getTeam()
- 테이블은 외래 키를 사용: JOIN ON M.TEAM_ID = T.TEAM_ID
객체에 맞추어 테이블 모델링
class Member {
String id; // MEMBER_ID 컬럼 사용
Long teamId; // TEAM_ID FK 컬럼 사용
String username; // USERNAME 컬럼 사용
}
class Team {
Long id; // TEAM_ID PK 사용
String name; // NAME 컬럼 사용
}
이 클래스를 테이블로 프레임워크가 매핑시켜 SQL을 만든다.
상황에 따라 동일한 회원 조회 매서드를 여러 벌 생성이 가능하다.
객체답게 모델링 할수록 매핑 작업만 늘어난다.
객체를 자바 컬렉션에 저장하듯이 데이터베이스에 저장할 수는 없을까?
JPA
JPA
Java Persistence API
자바 진영의 ORM 기술 표준
Why JPA?
- SQL 중심적인 개발에서 객체 중심으로 개발
- 생산성
- 유지보수
- 패러다임의 불일치 해결
- 성능
- 표준
JPA 문법 예시
- 저장: jpa.persist(member)
- 조회: Member member = jpa.find(memberId)
- 수정: member.setName("변경할 이름")
- 삭제: jpa.remove(member)
필드에 추가 되면 그냥 객체에 쓰기만 하면 됨
성능 개선
- 1. 1차 캐시와 동일성(Identity) 보장
- 2. 트랜잭션을 지원하는 쓰기 지연(transactional writ-behind)
- 3. 지연 로딩(Lazy Loading)
1차 캐시와 동일성 보장
1. 같은 트랜잭션 안에서는 같은 엔티티를 반환 - 약간의 조회 성능 향상
2. 디비 Isolation Level Read Commit이어도 애플리케이션에서 Repeatable Read 보장
트랜잭션을 지원하는 쓰기 지연 - INSERT
1. 트랜잭션을 커밋할 때까지 INSERT SQL을 모음
2. JDBC BATCH SQL 기능을 사용해서 한 번에 SQL 전송
트랜잭션을 지원하는 쓰기 지연 - INSERT
1. UPDATE, DELETE로 인한 로우(ROW)락 시간 최소화
2. 트랜잭션 커밋 UPDATE, DELETE SQL 실행하고, 바로 커밋
지연 로딩과 즉시 로딩
- 지연 로딩: 객체가 실제 사용될 때 로딩
- 즉시 로딩: JOIN SQL로 한 번에 연관된 객체까지 미리 조회
Transaction
Transaction이란?
데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 수행되어야할 일련의 연산들을 의미한다.
트랜잭션은 SELECT, UPDATE, INSERT, DELETE와 같은 연산을 수행하여 데이터베이스의 상태를 변화시키는 작업의 단위이다.
Transaction의 특징(ACID)
- Atomicity(원자성)
- 트랜잭션이 데이터베이스에 모두 반영되던지, 아니면 전혀 반영되지 않아야 한다.
- 트랜잭션 내의 모든 명령은 반드시 완벽히 수행되어야하며, 모두가 완벽히 수행되지 않고 어느 하나라도 오류가 발생하면 트랜잭션 전부가 취소되어야한다.
- Consistency(일관성)
- 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야한다.
- 시스템이 가지고 있는 고정요소는 트랜잭션 수행 전과 수행 완료 후의 상태가 같아야한다.
- Isolation(독립성)
- 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우 어떤 하나의 트랜잭션이라도 다른 트랜잭션의 연산에 끼어들 수 없다.
- 수행 중인 트랜잭션은 완전히 완료될 때까지 다른 트랜잭션에서 수행 결과를 참조할 수 없다.
- Durability(지속성)
- 트랜잭션이 성공적으로 완료되었을 경우, 결과는 영구적으로 반영되어야 한다.
트랜잭션의 Commit과 Rollback
- Commit - 하나의 트랜잭션이 성공적으로 끝났고, 데이터베이스가 일관성있는 상태에 있을 때 하나의 트랜잭션이 끝났음을 알려주기 위해 사용하는 연산
- Rollback - 하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터베이스의 일관성을 깨뜨렸을 때, 이 트랜잭션의 일부가 정상적으로 처리되었더라도 트랜잭션의 원자성을 구현하기 위해 이 트랜잭션이 행한 모든 연상을 취소하고(undo)하는 연산
- 활동(Active): 트랜잭션의 활동 상태. 트랜잭션이 실행중이며 동작중인 상태
- 부분완료(Partially Committed): 트랜잭션의 Commit 명령이 도착한 상태. 트랜잭션의 commit 이전 sql문이 수행되고 commit만 남은 상태
- 완료(Commited): 트랜잭션 완료 상태. 트랜잭션이 정상적으로 완료된 상태
- 실패(Failed): 트랜잭션 실패 상태. 트랜잭션이 더 이상 정상적으로 진행될 수 없는 상태
- 취소(Aborted): 트랜잭션 취소 상태. 트랜잭션이 취소되고 트랜잭션 실행 이전 데이터로 돌아간 상태
트랜잭션을 사용할 떄 주의할 점
- 트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다. 트랜잭션의 범위를 최소화하자
- 일반적으로 데이터베이스 커넥션은 개수가 제한적이다.
- 각 단위 프로그램이 커넥션을 소유하는 시간이 길어진다면 사용 가능한 여유 커넥션의 개수는 줄어듬
- 이러면 어느 순간에 각 단위 프로드램에서 커넥션을 가져가기 위해 기다려햐하는 상황이 발생할 수 있다.