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
복사했습니다!