
insert, update, select 등 명령 하나 하나가 Tx이다.
계좌 이체(update)는 출금 따로 입금 따로 작업을 할 수 없기 때문에 같이 묶어야 한다.
둘 다 성공하던가 / 하나만 실패해도 취소 -> All or Nothing
둘 이상의 작업을 어떻게 트랜잭션으로 묶을까?
우선 속성부터 배워보자

원자성
일관성 - 계좌 이체 전 과 후의 총 금액이 같아야한다.
고립성 - 서로의 작업(Tx1, Tx2)이 영향을 주면 안된다. (작업에 따라 Isolation Level을 적절하게 선택)
영속성

커밋을 해버리면, 롤백이 불가하다

자동 커밋 - 명령을 실행할 때마다 바로 커밋을 해버림 -> 롤백 불가
수동 커밋 - 내가 직접 커밋 명령을 내려줘야 커밋이 되는 것

각 트랜잭션을 고립시키는 정도를 나눠놓은 것
Serializable이 레벨이 가장 높다.
각 레벨을 알아보자

Tx1 -> 데이터 보기
Tx2 -> 데이터 삽입 (커밋 안함)
Tx1 -> 커밋도 안했는데 데이터 읽기 가능

Tx1의 두번째 명령문이 커밋된 데이터만 읽어올 수 있으므로 1,100만 남아있는 상태를 읽게 된다
Tx1이 진행하다보니 Tx2에 의해 DB가 업데이트되게 되는데,
이를 Pantom read라고 한다. (다른 트랜잭션의 영향을 받게 됨)

반복해서 읽을 수 있다
Tx1이 시작 된 후 Tx2가 아무리 작업을 하더라도 변경이 무시된다.
이 레벨이 Tx 속성 중 고립성을 만족시키므로 default 설정이다.

데이터가 작은 확률이라도 엉키지 않게 하기 위하려면 이 레벨을 선택해야 한다.
성능은 떨어지나 데이터 품질은 높아진다.
Tx1 트랜잭션이 끝날 때까지 Tx2가 작업하려는 것은 대기상태가 된다.
Tx1에서 커밋이 되고, 트랜잭션이 끝나면 Tx2의 작업이 시작된다.
<code />
@Test
public void TransactionTest() throws Exception{
Connection conn=null;
try {
deleteAll();
conn = ds.getConnection(); //데이터소스로부터 데이터베이스 연결을 가져온 뒤
conn.setAutoCommit(false); //AutoCommit을 꺼준다
String sql="insert into user_info values (?,?,?,?,?,?,now()) "; //sql문 작성
PreparedStatement pstmt = conn.prepareStatement(sql); //?에 해당하는 것들을 넣기
pstmt.setString(1, "asdf"); //sql injection 공격, 성능 향상
pstmt.setString(2, "1234");
pstmt.setString(3, "abc");
pstmt.setString(4, "aaa@aaa.com");
pstmt.setDate(5, new java.sql.Date(new Date().getTime()));
pstmt.setString(6, "fb");
int rowCnt = pstmt.executeUpdate(); //sql문 실행
pstmt.setString(1,"asdf");
rowCnt=pstmt.executeUpdate(); //sql문 실행
conn.commit();
} catch (Exception e) {
conn.rollback();
throw new RuntimeException(e);
} finally {
}
}
'패캠 챌린지' 카테고리의 다른 글
서비스계층(Layer)의분리, Transactional (0) | 2023.04.05 |
---|---|
AOP (0) | 2023.04.04 |
DAO의 작성과 적용 (0) | 2023.03.30 |
스프링으로 DB 다루기 (0) | 2023.03.29 |
Spring으로 DB 연결하기 (0) | 2023.03.28 |