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 을 통한 접근은 막히게 된다.
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 된다.
그러면 트랜잭션은 한꺼번에 모아서 실행하는 개념인가? 하면 한꺼번에 반영하거나 취소하는 개념은 맞지만 모아서 실행하는 개념과는 거리가 있다.
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();
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
와 동일