2번째 필수강의 ch3. 17강 요약 (Transaction, Commit, Rollback)
트랜잭션 Transaction
더 이상 나눌 수 없는 작업의 단위
- 원자성 (Atomicity)
나눌 수 없는 하나의 작업으로 다뤄져야 한다.- 일관성 (Consistency)
수행 전과 후가 일관된 상태를 유지해야 한다.- 고립성 (Isolation)
각 트랜잭션은 독립적으로 수행되어야 한다.- 영속성 (Durability)
성공한 트랜잭션의 결과는 유지되어야 한다.
- 커밋 Commit
작업 내용을 DB에 영구적으로 저장하는 것- 롤백 Rollback
최근 변경사항을 취소하는 것(=마지막 커밋으로 복귀)- 자동커밋 Auto Commit
명령 실행 후 자동으로 커밋이 수행되는 것(롤백 불가)- 수동커밋 Manual Commit
명령 실행 후 명시적으로 commit 또는 rollback을 입력하여 실행하는 것
아이솔레이션 레벨
- READ UNCOMMITTED (dirty read)
커밋되지 않은 데이터도 읽기 가능- READ COMMITTED (phantom read)
커밋된 데이터만 읽기 가능- REPEATABLE READ <DEFAULT>
하나의 트랜잭션이 시작된 이후의 다른 트랜잭션으로 인한 변경을 무시- SERIALIZABLE (직렬화)
한 번에 하나의 트랜잭션만 독립적으로 수행
+병렬로 DB에 작업을 하다보면 데이터의 품질이 떨어질 가능성이 있다.
트랜잭션을 테스트해본다. autocommit을 false로 두고, bbbb라는 user를 등록한다. 그리고 bbbb1라는 id만 달라진 user를 추가로 저장한다. 두 과정 중 한 과정에서라도 오류가 발생하면 rollback이 일어나 트랜잭션이 취소된다.
finally 내부에는 Connection을 닫아주는 내용이 들어가야 한다.
두번째로 저장하는 user의 id를 동일한 bbbb로 주었을 경우, Duplicate 에러가 발생해 롤백된다.
두 가지 경우 모두 테스트를 통과하는 것을 확인할 수 있었다.
@Test
public void testTransaction() throws Exception {
Connection conn = null;
try {
deleteAll();
conn = ds.getConnection();
conn.setAutoCommit(false);
// String sql = "insert into user_info values ('asdf', '1111', 'kim', 'aaa@aaa.com', '2022-12-02', 'twitter', now())";
String sql = "insert into user_info values (?,?,?,?,?,?,now())";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, "bbbb");
preparedStatement.setString(2, "1234");
preparedStatement.setString(3,"abc");
preparedStatement.setString(4, "aaa@bbb.com");
preparedStatement.setDate(5, new java.sql.Date(new Date().getTime()));
preparedStatement.setString(6,"instagram");
int rowCount = preparedStatement.executeUpdate();
preparedStatement.setString(1,"bbbb1");
rowCount = preparedStatement.executeUpdate();
conn.commit();
} catch (Exception e) {
conn.rollback();
e.printStackTrace();
} finally {}
}