✍🏻study/🎸기타

Auto Commit 오해

peacekim 2023. 6. 4. 23:36
반응형

글을 쓰게 된 계기

다른 팀원의 auto commit에 관한 발표를 듣고 궁금한 점이 생겼다.

Application 단에서, hikariCP의 auto commit 설정을 false로 하면, 디비에 요청시에, auto commit을 set하는 쿼리들이 날아가지 더 이상 날라가지 않아, DB 부하를 줄일 수 있고, DB 커넥션을 얻는 시간을 지연 시켜, 자원을 효율적으로 사용할 수 있다는 발표였다.

 

여기서 나는 궁금증이 생겼다.

 

HikcariCP의 auto commit 설정을 false로 하면, 트랜잭션의 auto commit 설정은 DB의 설정을 따라갈 것이다. 그래서, 우리 회사의 경우에는 auto commit이 true로 되어 있기에, 해당 transaction의 auto commit이 true가 설정된대로, 작동해야 된다고 생각했다.
나는 auto commit이라는 개념이 모든 쿼리마다 commit을 보장한다는 의미로 인지를 했다. 그렇기 때문에, insert문의 쿼리가 날라가고, 그 후에 auto commit이 바로 발생해, commit이 일어나고, 동일한 트랜잭션내에서 exception이 발생해도 저장된 값이 rollback이 되지 않아야 된다고 생각했다.

하지만, 실험해 본 결과 결과는 정상적으로 rollback이 됐다.

[ROLLBACK 쿼리도 나갔고, 실제로 데이터베이스에도 ROLLBACK됨]

auto commit의 개념을 잘못알고 있어, 이런 오해가 생긴거 같아 auto commit에 대한 개념을 알아보았다

 

Auto Commit이란?

In InnoDB, all user activity occurs inside a transaction. If autocommit mode is enabled, each SQL statement forms a single transaction on its own. By default, MySQL starts the session for each new connection with autocommit enabled, so MySQL does a commit after each SQL statement if that statement did not return an error. If a statement returns an error, the commit or rollback behavior depends on the error. See Section 15.21.5, “InnoDB Error Handling”.

A session that has autocommit enabled can perform a multiple-statement transaction by starting it with an explicit START TRANSACTION or BEGIN statement and ending it with a COMMIT or ROLLBACK statement. See Section 13.3.1, “START TRANSACTION, COMMIT, and ROLLBACK Statements”.

[MySQL 공식문서]

 

MySQL 공식 문서에 따르면, auto commit이 활성화 되어 있으면, 각 SQL이 단일 트랜잭션으로 형태이고, SQL에 문에 오류가 없다면, 자동으로 커밋이 수행된다. multip-statement 형태의 transaction도 수행가능하고, transaction을 명시적으로 열고, 마지막에 commit 또는 rollback을 쿼리를 날리면 된다.

 

이때는 transaction을 열지 않고, 각각의 쿼리를 날렸기 때문에, auto commit이 일어났을 경우, 이전 insert 쿼리가 반영이 안된다.

INSERT INTO `test` (`test_version`, `test_version_id`, `test_key`, `memo`, `manager_id`)
VALUES
('v1', '1versionId', 'test3Key', 'test', 'peace');

ROLLBACK;

transaction이 열었을 경우는,하나의 트랜잭션으로 봐서, rollback이 정상적으로 된다.

START TRANSACTION;
INSERT INTO `test` (`test_version`, `test_version_id`, `test_key`, `memo`, `manager_id`)
VALUES
	('v1', '1versionId', 'test3Key', 'test', 'peace');
	
ROLLBACK;

결론

각각의 쿼리가 단일 트랜잭션으로 시작되는 건 맞다. 하지만, 트랜잭션을 명시적으로 연다면, multiple-statement도 가능하다.

팀원이 말씀한대로 HikariCP의 auto commit 설정을 false로 하고, transactional 어노테이션만 명시적으로 잘 사용한다면, set auto commit 쿼리 없이, 간단한 성능 튜닝이 가능하다.


틀린 부분이 있다면, 댓글로 달아주시면 감사하겠습니다. 🙏

반응형