MySQL

03. 트랜잭션

erin.yoon 2020. 6. 15. 00:32

트랜잭션이란?

작업의 완정성을 보장해 주는 것으로, 논리적인 작업 셋 자체가 100% 적용되거나(COMMIT) 아무것도 적용되지 않아야(ROLLBACK) 한다.

하나의 논리적인 작업 셋에 쿼리가 몇 개 있는지는 중요하지 않다. 100%거나 0%여야 함을 보장해주는 것이 중요!

 

 

잠금과 트랜잭션

잠금 : 여러 커넥션에서 동시에 동일한 레코드나 테이블을 요청할 경우, 순서대로 한 시점에는 하나의 커넥션만 변경할 수 있게 해 주는 것(동시성 제어)

트랜잭션 : 데이터의 정합성 보장! 쿼리 중 일부라도 오류가 발생하면 전체를 원상태로 만들어 두는 것

격리 수준 : 하나의 트랜잭션 내에서 또는 여러 트랜지션 간의 작업 내용을 어떻게 공유하고 차단할 것인지를 결정하는 레벨

 

 

MySQL에서의 트랜잭션

mysql> CREATE TABLE tab_myisam (fdpk INT NOT NULL, PRIMARY KEY(fdpk)) ENGINE=MyISAM;
mysql> INSERT INTO tab_myisam (fdpk) VALUES (3);
mysql> CREATE TABLE tab_innodb (fdpk INT NOT NULL, PRIMARY KEY(fdpk)) ENGINE=INNODB;
mysql> INSERT INTO tab_innodb (fdpk) VALUES (3);

각 테이블에 레코드 1건씩 저장한 후, 다음 쿼리를 각각 InnoDB와 MyISAM에서 실행해 보면 어떤 차이가 있을까?

mysql> INSERT INTO tab_myisam(fdpk) VALUES(1),(2),(3);
mysql> INSERT INTO tab_innodb(fdpk) VALUES(1),(2),(3);

두 스토리지 엔진 모두 PRIMARY KEY 중복 오류로 쿼리가 실패한다. 그러나 두 테이블의 레코드를 조회해 보면 MyISAM 테이블은 오류가 발생했음에도 "1"과 "2"는 INSERT된 상태로 남아 있고, InnoDB에는 기존의 "3"만 있는 것을 확인할 수 있다.

mysql> SELECT * FROM tab_myisam;
+------+
| fdpk |
+------+
|    1 |
|    2 |
|    3 |
+------+
mysql> SELECT * FROM tab_innodb;
+------+
| fdpk |
+------+
|    3 |
+------+

즉, MyISAM은 차례대로 레코드를 저장하고, "3"을 저장하려는 순간 중복 키 오류가 발생한다. 여기서 이미 INSERT된 "1"과 "2"는 그대로 두고 쿼리 실행을 종료해 버린다. 반면에 InnoDB는 쿼리 중 일부라도 오류가 발생하면 전체를 원상태로 만들어 둔다는 트랜잭션의 원칙대로 INSERT문장을 실행하기 전 상태로 그대로 복구한다.

 

MyISAM의 이런 부분 업데이트 현상은 테이블 데이터의 정합성을 맞추는 데 상당히 어려운 문제를 만들어 낸다. 부분 업데이트 현상이 발생하면 실패한 쿼리로 인해 남은 레코드를 다시 삭제하는 재처리 작업이 필요해질 수 있다.

반응형