[MySQL] AutoCommit 과 DDL,DML,DCL

728x90

 

 


 

 

로컬에서 테이블 데이터를 비우기 위해서 truncate 를 계속 사용하고 있다가 테스트 DB 에서 테스트를 한 후
'truncate' 로 테이블 데이터를 지우는 것을 사수님이 보고 깜짝 놀라셨다

 

잠깐 당황했지만, 이유를 여쭤보았다

위 명령어는 최대한 지양 하라고 하고, 이유는 꼭 찾아보라고 말씀하셔서 제대로 공부를 해본 내용을 정리해보겠다

RDBMSMySQL8.0 을 기준으로 작성하였습니다

 

 

DDL (데이터 정의어)

보통 DBA 나 DB 를 관리하는 사람들이 자주 사용을 한다

작업단위는 '테이블(=객체)' 단위로 변화가 일어난다

exO schema, table, view, index

 

1) CREATE (테이블 생성, 스키마 생성)

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
);

 

2) ALTER (테이블 정보 수정)

ALTER TABLE users ADD email VARCHAR(100);

 

3) DROP (테이블 완전 삭제)

DROP TABLE users;

 

4) TRUNCATE (테이블 데이터 초기화)

TRUNCATE TABLE users;

 

⭐️ 중요한건 위 DDL 들은 AutoCommit 이 내포되어 있어, 실행하면 바로 DB에 적용이 된다 ⭐️

MySQL Autocommit 과 관계없이 위 설정이 해제되어 있어도 자동으로 커밋이 된다.

 

즉 Rollback 이 되지않아 신중하게 사용해야 한다는 뜻이다. 특히 'DROP, TRUNCATE'

 

 

DML (데이터 조작어)

DML 은 'CRUD' 작업을 하기위한 대표적인 쿼리이다

보통 서버 개발자분들이 위 쿼리를 셀수 없이 사용하고 있을 것이라고 생각한다^~^

위 명령어들을 작업단위는 'row' 행 별로 일어나게 된다

테이블 단위로 변화가 일어나는 DDL 과 차이가 있다

 

1) INSERT (행 삽입)

INSERT INTO users (name, email) VALUES ('jin', 'jin@google.com');

 

2) UPDATE (행 수정)

UPDATE users SET name = 'hkjin' WHERE id = 1;

 

3) DELETE (행 삭제)

DELETE FROM users WHERE id = 1;

 

AutoCommit 이 되지 않아, rollback 이 가능하다.

 

하지만 보통 스프링부트에 JPA 를 사용하면 트랜잭션 관리가 가능하기 떄문에 트랜잭션이 성공적으로 일어나면
commit 을 하는 로직이 포함되어 있어 자동으로 commit 이 되는 편이다

 

 

DCL (데이터 정의어)

위 쿼리 또한 보통 DBA 나 DB 를 관리하는 사람들이 자주 사용을 한다

1) grant (권한부여)

GRANT insert ON payment TO 'user1'@'localhost';

user1@localhost 에게 payment 테이블에 insert 권한을 준다는 뜻이다

 

2) revoke (권한회수)

REVOKE insert ON payment FROM 'user1'@'localhost';

 

반대로 user1@localhost 가 payment 테이블에 가지고 있는 insert 권한을 회수한다는 뜻이다

 

만약 다른 권한을 부여하고 싶다면 grant(revoke) [ ] on 이 중간에 명령어를 바꿔주면 된다

위 쿼리들은 보다시피 관리자가 DB 에 접속할 수 있는 계정마다 권한을 부여하고 회수할 때 사용한다

보통 관리자는 백엔드 개발자한테는 DML 만 사용할 수있는 권한을 부여하고, DDL,DCL 권한은 부여하지 않는다

리눅스 서버에서 sudo 권한을 주지 않는 것이랑 비슷한 느낌이다

 

⭐️ 중요한건 AutoCommit 이 내포되어 있어, 실행하면 바로 DB에 적용이 된다 ⭐️

MySQL Autocommit 과 관계없이 위 설정이 해제되어 있어도 자동으로 커밋이 된다.

 

rollback 이 되지않아 신중하게 사용할 필요가 있는 쿼리들이라고 생각한다

 

 

[DDL,DCL 과 트랜잭션 autocommit 의 관계]
[DCL 기준 예시]

SET autocommit = 0;  -- 트랜잭션 자동 커밋 해제
START TRANSACTION;  -- 트랜잭션 시작
GRANT SELECT ON mysql TO 'user2'@'localhost';
ROLLBACK; -- 권한 변경은 롤백되지 않음

 

위 쿼리를 한번 직접 날려보시면 알 수 있다.

Autocommit 이 해제되어 있어도 'Grant' 는 위와 무관하게 commit 이 되어있음을 알 수 있다

 

🖐🏻왜 DCL 명령어는 autocommit 과 무관할까?

DML, DCL 의 특성 상 보통 관리자가 작업을 할 때 사용한다

즉 위 명령어들은 User 에게 직접적인 영향을 미치므로 트랜잭션의 롤백 대상이 되지 않도록 설계되어 있다

즉 DB 상태에 직접적인 영향을 끼치므로, 명령어 실행 후 즉시 commit 되게 설계가 되어있다

 

TCL (트랜잭션 제어언어)

1) commit

  • 트랜잭션의 결과를 영구적으로 DB 에 반영한다.

2) rollback

  • DB 를 마지막 commit 된 시점의 상태로 복원한다.

3) savepoint

  • Rollback 시 트랜잭션에 포함된 전체 복원이 아닌 savepoint 까지 트랜잭션의 일부만 롤백 가능

위 명령어 들은 보다 시피 '' 에 적용되는 것이 아닌 '테이블(=객체)' 전체에 적용이 된다.

위 부분을 꼭 알고 있어야 한다.

 

@AutoCommit 은 좋은건가?

결론만 말씀하자면 거의 대부분 사람들은 사용하고 있을 것이라고 생각한다

MySQL 같은 경우는 자동으로 AutoCommit 설정이 되어있다

 


AutoCommit 이 설정 되어있고 안되어있고 차이는 트랜잭션이 일어나는 것을 보면 알 수 있다

DB 에서 'Create' 'Update' 'Delete' 가 일어나는 것을 '트랜잭션' 이라고 부른 다는 건 다들 알고 있을 것이다

 


트랜잭션은즉 DB 의 상태에 변경을 주는 것들을 지칭한다

그리고 트랜잭션이 발생한 이후에 현재는 자동으로 Commit 을 통하여 DB 에 작업이 반영이 된다.

즉 우리가 모르고 있었지만, 우리의 트랜잭션은 sql 쿼리를 날리고 'commit(=영구저장)' 이 되어야 DB 에 변경이 일어나는 것이다

 


위 기능을 @AutoCommit 이 자동으로 commit 쿼리를 날려주고 있던 것 이다

AutoCommit 을 확인하기 위해선

SELECT @@AUTOCOMMIT;

 

명령어를 실행시키면 결과물이 1로 되있을 것 입니다.


1 은 @AutoCommit 이 되어있는 상태이고 위 AutoCommit 을 해제하기 위해선 숫자를 '0' 으로 바꾸면 됩니다.

SET AUTOCOMMIT = 0; -- autocommit [해제]
SET AUTOCOMMIT = 1; -- autocommit [설정]

 

AutoCommit 을 해제한 후에는 이제 트랜잭션에 대한 롤백도 가능하다

하지만 트랜잭션이 일어난 이후 'commit' 을 매번 해줘야 하는 귀찮음 또한 있다

하지만 데이터가 중요한 작업을 하는 경우에는 autocommit 을 비활성화 후 트랜잭션을 수동으로 관리하는 것은 괜찮은 방법이라고 생각합니다

 

ORM 인 JPA 를 사용하고 있다면 자체적으로 영속성 컨텍스트 및 DB 트랜잭션을 관리할 수 있다

그리고 스프링을 사용중이라면 @Transactional 을 통하여 트랜잭션 실패시 롤백 되는 기능을 사용할 수도 있다

Spring Framework와 같은 애플리케이션에서는 트랜잭션을 코드 레벨에서 처리하기 때문에,

 


MySQL의 autocommit 설정은 보통 애플리케이션 레이어에서 관리됩니다.

즉 MySQL workbench 나 datagrip 같은 툴에서 직접적인 트랜잭션이 발생할 일 은 크게 많지는 않을 것이다

 


그러므로 트랜잭션에 Commit 같은 경우는 Persistence Layer 쪽을 다뤄야 하는 경우가 많을 것이다

즉 위 내용을 자세하게 알기 위해서는 '트랜잭션 격리 수준' 에 대한 학습이 필요할 것이라고 생각합니다

 

그러므로 Service Layer 에서 트랜잭션을 관리하되, DB tool 에서는 최대한 직접적인 제어는 지양해야 하겠지만,
그럼에도 불구하고 트랜잭션이 발생할 일이 있을 것 이기 때문에 조심해서 사용하기 위해 @Autocommit 을 해제 후 여러번 확인하고 직접 commit 을 하는 방법을 추천한다.

 

 

728x90