Insert 후 ID를 리턴하고 싶은 경우 LAST_INSERT_ID()를 사용하면 된다.

MyBatis의 경우 selectKey 문을 이용하여 사용 가능하다.

<insert id="addUser" parameterType="User">
  INSERT INTO TB_USER VALUES ( // 생략)
  <selectKey keyProperty="id" resultType="Integer">
    SELECT LAST_INSERT_ID()
  </selectKey>
</insert>        

참고로 리턴값에 담기는게 아니라 파라미터로 넘긴 User 객체에 id가 담긴다.

동시다발로 요청을 하는 경우 이 값이 계속 업데이트되면 문제가 되지 않을까 생각했는데, 그렇지 않다.
MySQL 공식 문서에 따르면 다음과 같다.

For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.

커넥션 별로 _LAST_INSERT_ID_가 관리되므로 여러개의 요청이 동시에 발생해도 문제가 없다.

'개발 > 데이터베이스' 카테고리의 다른 글

ACID (Atomicity, Consistency, Isolation, Durability)  (0) 2020.02.03

ACID

데이터베이스의 트랜잭션이 중간에 실패가 나거나 예기치 못한 상황이 발생해도 데이터를 유효한 상태를 보장하기 위해서 만족해야하는 조건들이다.

Atomicity

트랜잭션은 성공 or 실패다.
부분 성공은 없다.
ex) A 통장에서 돈을 빼서 B 통장으로 입금하는 시나리오에서 A 통장에서 돈만 빼오고 실패하는 경우가 발생하면 안된다.
이를 위해 커밋과 롤백의 개념이 있다.

Consistency

너무 포괄적인 단어여서 정리하기 어려웠다.
일관성은 내가 정의한 룰을 지키는 유효한 상태에 있게끔 보장해야 한다는 것인데, 여러가지 측면이 될 수 있다.

  • 가장 단순하게는 자료형이 있을 수 있다.
    정수형 데이터에 실수가 들어갈 수 없다.
  • 값에 조건이 있을 수도 있다.
    A+B=100이어야 한다는 룰이 있을 때 트랜잭션 중 A+B=90인 상태가 된다면 해당 트랜잭션은 실패해야 한다.
  • 여러 테이블에 데이터가 중복되는 경우의 문제일 수 있다.
    성능상의 이유로 역정규화된 테이블을 유지한다고 해보자. 테이블1.A=90이면 테이블2.A=90이야 한다. 하지만 잘못된 트랜잭션 관리로 테이블2.A=80이 되는 순간에 일관성은 깨진다.
  • 테이블간의 참조에 의한 문제일 수 있다.
    테이블1에 있는 데이터를 테이블2가 참조한다고 할 때 참조되고 있는 테이블1의 데이터는 삭제되선 안된다.

Isolation

다른 트랜잭션 연산 작업이 끼어들지 못하도록 보장하는 것
성능상의 이유로 이 특성은 가장 유연성 있는 제약 조건이다.

Durability

성공적으로 트랜잭션이 수행되었다면 그 결과를 보존해야한다. 중간에 시스템 문제(전력 차단등)로 인해 로그가 유실된다거나 하는 문제가 없어야 한다. 비휘발성 메모리에 커밋된 로그를 보존하는 방식이 될 수 있다. 

'개발 > 데이터베이스' 카테고리의 다른 글

[MySQL] Insert 후 ID 받아오기 (MyBatis)  (2) 2020.05.19

+ Recent posts