Transaction
더 이상 나눌 수 없는 작업의 단위
Transaction 의 속성 - ACID
원자성(Atomicity) - 나눌 수 없는 하나의 작업으로 다뤄주어야 한다.
일관성(Consistency) - Tx 수행 전과 후가 일관된 상태를 유지해야 한다.
고립성(Isolation) - 각 Tx는 독립적으로 수행되어야 한다.
영속성(Durability) - 성공한 Tx의 결관느 유지되어햐 한다.
커밋(Commit), 롤백(Rollback)
커밋 : 작업 내용을 DB에 영구적으로 저장
롤백 : 최근 변경사항을 취소(마지막 커밋으로 복귀)
Tx의 isolation level
READ UNCOMMITED - 커밋되지 않은 데이터도 읽기 가능(dirty read)
READ COMMITED - 커밋된 데이터만 읽기 가능(phantom read)
REPEATABLE READ - TX이 시작된 이후 변경은 무시됨(defualt)
SEEIALIZABLE - 한 번에 하나의 TX만 독립적으로 수행(고립도 최고)
TX 테스트
2개의 다른 id값을 insert 한 후에 commit 을 해서 2개의 값이 DB에 저장 되었다.
trasactionTest.java
@Test
public void transactionTest() throws Exception {
Connection conn=null;
try {
deleteAll();
conn = ds.getConnection();
conn.setAutoCommit(false);
// INSERT INTO `usedhunter`.`user_info`(`id`,`pwd`,`name`,`email`,`birth`,`sns`,`reg_date`)
// VALUES('asdf2','1234','smith','aaa@aaa.com','2021-01-01','facebook',now());
String sql = "INSERT INTO `usedhunter`.`user_info` VALUES(?, ?, ?, ?, ?, ?, now())";
PreparedStatement pstmt = conn.prepareStatement(sql); // SQL injection 방어에 유리, 성능 향상
pstmt.setString(1, "asdf");
pstmt.setString(2, "1234");
pstmt.setString(3, "abc");
pstmt.setString(4, "aaa@aaa.com");
pstmt.setDate(5, new java.sql.Date(new Date().getTime())); // util.Date 인 user.getBirth() 를 sql.Date 로 변환
pstmt.setString(6, "fb");
int rowCnt = pstmt.executeUpdate(); // 영향 받은 로우행 개수 반환, insert, delete, update 에 사용
pstmt.setString(1, "asdf2");
rowCnt = pstmt.executeUpdate();
conn.commit();
} catch (Exception e) {
conn.rollback();
e.printStackTrace();
} finally {
}
}
2개의 같은 id값을 insert 하고 commit
rollback 되었다.
@Test
public void transactionTest() throws Exception {
Connection conn=null;
try {
deleteAll();
conn = ds.getConnection();
conn.setAutoCommit(false);
// INSERT INTO `usedhunter`.`user_info`(`id`,`pwd`,`name`,`email`,`birth`,`sns`,`reg_date`)
// VALUES('asdf2','1234','smith','aaa@aaa.com','2021-01-01','facebook',now());
String sql = "INSERT INTO `usedhunter`.`user_info` VALUES(?, ?, ?, ?, ?, ?, now())";
PreparedStatement pstmt = conn.prepareStatement(sql); // SQL injection 방어에 유리, 성능 향상
pstmt.setString(1, "asdf");
pstmt.setString(2, "1234");
pstmt.setString(3, "abc");
pstmt.setString(4, "aaa@aaa.com");
pstmt.setDate(5, new java.sql.Date(new Date().getTime())); // util.Date 인 user.getBirth() 를 sql.Date 로 변환
pstmt.setString(6, "fb");
int rowCnt = pstmt.executeUpdate(); // 영향 받은 로우행 개수 반환, insert, delete, update 에 사용
pstmt.setString(1, "asdf");
rowCnt = pstmt.executeUpdate();
conn.commit();
} catch (Exception e) {
conn.rollback();
e.printStackTrace();
} finally {
}
}
'Spring > Ch3. Spring DI, AOP' 카테고리의 다른 글
Spring - 서비스 계층의 분리와 @Transactional (0) | 2022.09.30 |
---|---|
Spring - AOP (0) | 2022.09.30 |
Spring DI - Spring DI 흉내내기 (0) | 2022.09.25 |
Spring - Spring DI(1) (0) | 2022.09.13 |
Ch3-3_Spring DI 활용하기 - 이론 (0) | 2022.02.08 |