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 특성
- Atomicity (원자성)
- 트랜잭션에 포함된 모든 작업이 모두 성공하거나, 모두 실패해야 합니다.
- 예: 돈을 계좌 A에서 계좌 B로 이체할 때, A에서 돈을 빼고 B에 넣는 두 작업이 하나의 트랜잭션으로 처리되어야 합니다. 하나라도 실패하면 작업은 취소됩니다.
- Consistency (일관성)
- 트랜잭션 실행 전후에 데이터베이스의 상태가 항상 일관성을 유지해야 합니다.
- 예: 은행 계좌에서 이체한 후에도 총 잔액은 변하지 않아야 합니다.
- Isolation (격리성)
- 여러 트랜잭션이 동시에 실행될 때, 각 트랜잭션은 서로 간섭하지 않고 독립적으로 실행되어야 합니다.
- 예: 두 사용자가 동시에 같은 데이터를 업데이트하더라도 서로에게 영향을 주지 않습니다.
- Durability (지속성)
- 트랜잭션이 성공적으로 완료되면, 결과가 영구적으로 저장됩니다.
- 예: 시스템이 중단되더라도 트랜잭션의 결과는 데이터베이스에 반영되어야 합니다.
왜 트랜잭션이 중요한가?
트랜잭션은 데이터의 무결성과 일관성을 유지하는 데 중요한 역할을 합니다. 특히 여러 작업이 연속적으로 수행될 때 문제가 발생할 가능성이 있을 때 유용합니다.
예시: 좌석과 직원 삭제
seats
테이블과employee
테이블에서 데이터를 삭제하는 두 작업이 있습니다.- 만약 첫 번째 작업(
seats
삭제)은 성공했지만, 두 번째 작업(employee
삭제)은 실패하면 데이터베이스 상태가 불완전하게 됩니다. - 트랜잭션을 사용하면 두 작업이 모두 성공해야만 데이터베이스에 반영되고, 하나라도 실패하면 롤백(Rollback) 되어 이전 상태로 복구됩니다.
GoLang에서 트랜잭션의 사용
- 트랜잭션 내에서 데이터베이스 작업을 수행할 때,
tx
라는 변수를 사용한다. - tx는 트랜잭션을 나타내는 GROM의 DB객체이다.
- 트랜잭션 내에서 수행되는 모든 작업을 하나의 트랜잭션으로 처리하게 된다.
- 트랜잭션이
nil
을 반환한다는 것은 에러가 발생하지 않았다는 의미로, 트랜잭션이 성공되었다고 간주되어 커밋이 수행된다.