[211216] 교육 46일차

oxllz·2022년 2월 19일
0

교육

목록 보기
31/41

트랜잭션


AUTOCOMMIT : INSERT/ DELETE/ UPDATE 문장을 수행했을때 LOG 를 거지지 않고 곧바로 반영한다. AUTOCOMMIT 을 FALSE 로 지정하면 INSERT/ DELETE/ UPDATE 한 내역은 Table 에 반영되지 않고 LOG 에 쌓이게 된다.
( 이때, SQL 문장을 수행한 A는 LOG 를 거쳐 변경된 내용을 table 에서 확인이 가능하지만 B는 확인 불가 )

AUTOCOMMIT 여부 확인 ( Default값 : 1 )

SELECT @@AUTOCOMMIT;

AUTOCOMMIT 해제

SET AUTOCOMMIT=FALSE;

COMMIT

COMMIT;

ROLLBACK

ROLLBACK;

COMMIT : LOG가 비워지고 동시에 테이블에 반영 -> B도 확인이 가능해짐
ROLLBACK : LOG에 쌓인 내역은 테이블에 반영되지 않고 버려진다.

LOCK : 레코드에 수정이 이루어지면 해당 레코드는 LOCK 이 걸리게 되고, COMMIT/ ROLLBACK 이 결정되는 시점에서 LOCK 이 풀리게 된다. 그때까지 다른 connection 을 통한 접근은 막히게 된다.


JDBC 에서의 트랜잭션 보장

public class Test306 {
	public static void main( String[] args ) throws Exception {
		Connection conn = null;
		Statement stmt = null;
		try {
			Class.forName("org.mariadb.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mariadb://...", "...", "...");
			conn.setAutoCommit( false );
			stmt = conn.createStatement();
			//
			String sql1 = "UPDATE Text_HT SET recom = recom + 1 WHERE no = 2";
			String sql2 = "INSERT Recom_HT VALUES ( 2, 'Apple')";
			stmt.executeUpdate( sql1 );
			stmt.executeUpdate( sql2 );
			conn.commit();	//	COMMIT; 과 동일한 역할 - 테이블 반영 & 로그 비운다.
		}
		catch( Exception e ) {
			if( conn != null )
				conn.rollback();	//  ROLLBACK; 과 동일역할
			throw e;
		}
		finally {
			if( stmt != null ) stmt.close();
			if( conn != null ) conn.close();
		}
	}
}

setAutoCommit() : AUTOCOMMIT 설정
conn.commit();
conn.rollback(); : 에러가 발생하면 catch 되어 rollback 된다.


BatchUpdate


그러면 트랜잭션은 한꺼번에 모아서 실행하는 개념인가? 하면 한꺼번에 반영하거나 취소하는 개념은 맞지만 모아서 실행하는 개념과는 거리가 있다.

stmt = conn.createStatement();
String sql1 = "UPDATE Text_HT SET recom = recom + 1 WHERE no = 3";
String sql2 = "INSERT Recom_HT VALUES ( 3, 'Apple')";
//	실행하는 명령이 아니라 차곡차곡 쌓아 놓으라는 명령
stmt.addBatch( sql1 );
stmt.addBatch( sql2 );
//	가서 실행하고 담아서 돌아오라는 명령
stmt.executeBatch();

BatchUpdate & PreparedStatement

String sql2 = "INSERT temp14_T VALUES ( ?, 'K')";
stmt = conn.prepareStatement( sql2 );
for( int i = 10 ; i < 15 ; i++ ) {
	stmt.setInt( 1, i );
	stmt.addBatch();
	//	PreparedStatement 로 여러번 값을 바꾸어서 addBatch 할 경우에 써 준다.
	stmt.clearParameters();
}
stmt.executeBatch();

이 코드에서 생성한 stmt 는 딱 한개다. stmt.addBatch(); 를 5번 했을때 이건 5개의 SQL 문이 탑재되었다는 의미인데 하나의 Statement 로 5개의 SQL 문장을 실행시키는게 될까?

--> stmt.clearParameters();
PreparedStatement 에서 ? 를 채워넣었던 이전의 데이터를 비워주어서 새로이 값을 세팅할 수 있도록 밑 작업을 해 준다.


프로시저의 트랜잭션 보장

프로시저 안에서 트랜잭션을 보장해주면 JDBC 에서는 보장해줄 필요가 없다.

DELIMITER //
CREATE PROCEDURE proc_tx4( IN v_no INT, IN v_uid VARCHAR(10) )
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    ROLLBACK;
	RESIGNAL;
  END;
  START TRANSACTION;
  UPDATE Text_HT SET recom = recom + 1 WHERE no = v_no;
  INSERT INTO Recom_HT VALUES ( v_no, v_uid );
  COMMIT;
END;
//
DELIMITER ;

DECLARE EXIT HANDLER FOR SQLEXCEPTION : 에러가 나면 이 영역을 실행한다.
RESIGNAL; : 발생된 에러 그대로 재발생. throw e 와 동일

0개의 댓글