GoLang 트랜잭션(자리배치표 만들기 2)

package handlers

import (
	"net/http"

	"mw-seat/db"

	"github.com/gorilla/mux"
)

// DeleteHandler handles DELETE requests to remove a seat by ID.
func DeleteHandler(w http.ResponseWriter, r *http.Request) {
	name := mux.Vars(r)["name"]

	// DB에서 자리 삭제
	_, err := db.Pool.Exec(r.Context(), "DELETE FROM seats WHERE name = $1", name)
	if err != nil {
		http.Error(w, "Unable to delete seat", http.StatusInternalServerError)
		return
	}
	_, err := db.Pool.Exec(r.Context(), "DELETE FROM employee WHERE name_en = $1", name)

	w.WriteHeader(http.StatusOK)
}

자리배치표를 만듦에 있어 postgresql 에서 두 개의 table (seats, employee) 를 사용하고 있다.

seats 에서 삭제 SQL 코드만 있어 _, err := db.Pool.Exec(r.Context(), "DELETE FROM employee WHERE name_en = $1", name) 와 같이 추가했더니 에러가 발생하였다.

에러의 원인은 GPT는 다음과 같이 설명해주고 있다.

  • 1. 문법 오류 (중복된 변수 선언)

Go에서는 같은 스코프에서 동일한 이름의 변수를 두 번 선언할 수 없습니다. 아래 코드에서 err 변수가 두 번 선언되고 있습니다.

  • 2. 트랜잭션 누락

seats에서 삭제가 성공하더라도 employee에서 삭제가 실패하면 데이터가 불일치 상태에 놓일 수 있습니다. 이를 방지하기 위해 트랜잭션을 사용하는 것이 좋습니다.


트랜잭션(Transaction)이란 무엇인가?

트랜잭션은 데이터베이스에서 하나의 작업 단위를 말하며, 여러 작업을 하나로 묶어 실행합니다. 트랜잭션은 일관성과 무결성을 보장하기 위해 아래 네 가지 특성을 준수합니다. 이를 ACID라고 합니다.

트랜잭션(Transaction)이란?

트랜잭션은 데이터베이스에서 하나의 작업 단위를 말하며, 여러 작업을 하나로 묶어 실행합니다. 트랜잭션은 일관성과 무결성을 보장하기 위해 아래 네 가지 특성을 준수합니다. 이를 ACID라고 합니다.

ACID 특성

  1. Atomicity (원자성)
    • 트랜잭션에 포함된 모든 작업이 모두 성공하거나, 모두 실패해야 합니다.
    • 예: 돈을 계좌 A에서 계좌 B로 이체할 때, A에서 돈을 빼고 B에 넣는 두 작업이 하나의 트랜잭션으로 처리되어야 합니다. 하나라도 실패하면 작업은 취소됩니다.
  2. Consistency (일관성)
    • 트랜잭션 실행 전후에 데이터베이스의 상태가 항상 일관성을 유지해야 합니다.
    • 예: 은행 계좌에서 이체한 후에도 총 잔액은 변하지 않아야 합니다.
  3. Isolation (격리성)
    • 여러 트랜잭션이 동시에 실행될 때, 각 트랜잭션은 서로 간섭하지 않고 독립적으로 실행되어야 합니다.
    • 예: 두 사용자가 동시에 같은 데이터를 업데이트하더라도 서로에게 영향을 주지 않습니다.
  4. Durability (지속성)
    • 트랜잭션이 성공적으로 완료되면, 결과가 영구적으로 저장됩니다.
    • 예: 시스템이 중단되더라도 트랜잭션의 결과는 데이터베이스에 반영되어야 합니다.

왜 트랜잭션이 중요한가?

트랜잭션은 데이터의 무결성과 일관성을 유지하는 데 중요한 역할을 합니다. 특히 여러 작업이 연속적으로 수행될 때 문제가 발생할 가능성이 있을 때 유용합니다.

예시: 좌석과 직원 삭제

  • seats 테이블과 employee 테이블에서 데이터를 삭제하는 두 작업이 있습니다.
  • 만약 첫 번째 작업(seats 삭제)은 성공했지만, 두 번째 작업(employee 삭제)은 실패하면 데이터베이스 상태가 불완전하게 됩니다.
  • 트랜잭션을 사용하면 두 작업이 모두 성공해야만 데이터베이스에 반영되고, 하나라도 실패하면 롤백(Rollback) 되어 이전 상태로 복구됩니다.

GoLang에서 트랜잭션의 사용

  • 트랜잭션 내에서 데이터베이스 작업을 수행할 때, tx라는 변수를 사용한다.
  • tx는 트랜잭션을 나타내는 GROM의 DB객체이다.
  • 트랜잭션 내에서 수행되는 모든 작업을 하나의 트랜잭션으로 처리하게 된다.
  • 트랜잭션이 nil을 반환한다는 것은 에러가 발생하지 않았다는 의미로, 트랜잭션이 성공되었다고 간주되어 커밋이 수행된다.