Go 언어에서 ORM으로 GORM을 쓰다 보면 관계 설정 말고도 놓치기 쉬운 고급 기능들이 있다.
이번 글에서는 실무에서 정말 유용하게 쓰이는 Soft Delete, Hooks, 트랜잭션을 정리해보자.
📌 목차
Soft Delete란?
GORM Hooks란?
트랜잭션 다루기
마무리 및 다음 예고
1. Soft Delete란?
Soft Delete는 데이터를 물리적으로 삭제하지 않고, 삭제된 것처럼 다루는 기능이다.
🧾 사용법
import "gorm.io/gorm"
type User struct {
ID uint
Name string
DeletedAt gorm.DeletedAt `gorm:"index"`
}
DeletedAt 필드를 추가하면 GORM이 자동으로 Soft Delete를 처리함
Delete() 호출 시 DeletedAt에 시간이 기록되고, 일반 쿼리에서는 자동으로 제외됨
🔧 사용 예
db.Delete(&user) // 실제 삭제 ❌ -> DeletedAt에 timestamp만 기록
db.Find(&user) // 기본적으로 Soft Deleted 데이터는 조회되지 않음
❗복구하기
db.Unscoped().Find(&user) // Soft Deleted 포함 조회
user.DeletedAt = nil
db.Unscoped().Save(&user) // 복구
2. GORM Hooks
Hooks는 GORM이 특정 작업 전에 자동으로 호출해주는 함수다.
Before/After Create, Update, Delete 등 다양한 지점에서 사용할 수 있다.
🔧 예제: BeforeCreate
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
u.Name = strings.ToUpper(u.Name)
return
}
Create() 호출 전 이름을 대문자로 바꾸는 훅
BeforeUpdate, AfterDelete, AfterFind 등도 있음
🧩 활용 팁
공통 필드 자동 설정
유효성 검사
감사 로그(Audit) 기록
⚠️ 주의: Hook 내부에서 tx.Save() 같은 DB 작업을 부르면 무한 루프 가능성 있음
3. 트랜잭션
트랜잭션은 여러 DB 작업을 하나의 단위로 묶는 기능이다.
에러가 발생하면 전체 작업을 되돌릴 수 있어서 데이터 무결성을 보장할 수 있다.
🔧 기본 예제
err := db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&user).Error; err != nil {
return err
}
if err := tx.Create(&profile).Error; err != nil {
return err
}
return nil
})
중간에 하나라도 실패하면 모든 작업이 롤백됨
Transaction() 함수 안에서 작업을 처리해야 함
🧱 수동 트랜잭션 관리
tx := db.Begin()
if err := tx.Create(&user).Error; err != nil {
tx.Rollback()
return
}
if err := tx.Create(&profile).Error; err != nil {
tx.Rollback()
return
}
tx.Commit()
수동 관리가 필요한 경우 (조건부 처리, 분기 로직 등)에도 유용
🔍 팁: 트랜잭션 안에서 Hook도 작동한다!
db.Transaction(func(tx *gorm.DB) error {
return tx.Create(&user).Error // Hook 정상 작동
})
Hook은 트랜잭션 내에서도 실행된다.
트랜잭션이 롤백되면 Hook의 영향도 되돌아감
✅ 마무리
이번 글에서는 실무에서 자주 쓰이지만 문서로는 잘 안 정리되어 있는 GORM의 고급 기능들을 살펴봤다.
기능 | 설명 |
Soft Delete | 삭제된 데이터는 숨기고 나중에 복구 가능 |
Hooks | 작업 전/후 자동으로 동작하는 커스텀 로직 |
트랜잭션 | 다단계 작업을 한 번에 처리하고 실패 시 되돌릴 수 있음 |
'개발 > Go' 카테고리의 다른 글
[Gin] GORM 마이그레이션 전략 - 자동 vs 수동 관리, 안전하게 스키마 관리하기 (35) | 2025.06.06 |
---|---|
[Gin] GORM 성능 최적화 팁 - Preload, Select, Index 전략까지! (64) | 2025.06.04 |
[Gin] GORM 관계 설정 완전 정복 - 1:N, N:1, N:M 예제로 배우기 (60) | 2025.05.26 |
[Gin] Go + Gin + GORM으로 백엔드 만들기 (기초부터 CRUD까지) (41) | 2025.05.24 |
[Gin] Gin 시작해보자! (95) | 2025.05.14 |