6주차 Unit 6.3 — Consistency (일관성)

Psj·2026년 6월 1일

F-lab

목록 보기
204/239

Unit 6.3 — Consistency (일관성)

F-LAB JAVA · 6주차 · Phase 6 · 트랜잭션과 ACID
★ 깊이 파기 — ACID 의 두 번째, "제약조건은 항상"


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • Consistency (일관성) 의 정의는?
  • "제약조건이 항상 지켜져야" 의 의미는?
  • 제약조건 종류 (NOT NULL/UNIQUE/CHECK/FK) 는?
  • 잔액 음수 불가 같은 제약은?
  • 깨지는 트랜잭션은 자동 롤백 동작은?
  • 일관성 vs 무결성 (Integrity) 차이는?
  • DB 가 일관성을 감지 하는 방식은?
  • 비즈니스 규칙은 어디서 강제하나?
  • Spring/JPA 의 일관성 처리 는?

🎯 핵심 한 문장

Consistency (일관성) 는 트랜잭션 완료 후 DB 의 모든 제약조건 (NOT NULL/UNIQUE/CHECK/FOREIGN KEY) 이 항상 지켜져 일관된 상태가 되어야 한다는 성질로, 제약을 깨는 트랜잭션은 DB 가 자동으로 rollback 하며 비즈니스 규칙 같은 더 큰 일관성은 보통 애플리케이션이 강제한다.
Consistency (일관성) 는 트랜잭션이 완료된 후 DB 가 항상 일관된 상태 를 유지해야 한다는 성질이다.
일관성은 주로 제약조건 (Constraint) 으로 표현되며 — NOT NULL (필수), UNIQUE (중복 X), CHECK (값 범위), FOREIGN KEY (참조 무결성), 그리고 도메인의 비즈니스 규칙 (예: 잔액 음수 X) 등이 있다.
트랜잭션 중 제약을 깨는 시도가 감지되면 DB 가 자동으로 전체 트랜잭션을 rollback 하여 일관된 상태를 보장한다.
다만 일관성은 데이터의 정합성(Integrity) 과 유사하지만 좀 더 넓은 개념 — DB 제약은 DB 가, 비즈니스 규칙은 보통 애플리케이션 이 강제하며 (예: Spring 의 @PrePersist, 도메인 메서드), JPA 도 엔티티 제약 (@NotNull, @Size, @AssertTrue) 으로 일관성을 도와준다.

비유 — 회계 장부의 균형 (차변 = 대변)

Consistency = 회계 장부 균형:

장부 규칙 (제약조건):
  - 차변 합 = 대변 합 (항상)
  - 잔액 ≥ 0 (음수 X)
  - 계정 코드 존재 (FK)
  - 거래 일자 필수 (NOT NULL)

트랜잭션 후:
  - 모든 규칙 만족
  - 깨지면 → 거래 무효 (rollback)

DB 제약 (자동 감지):
  - NOT NULL: 빠진 값 X
  - UNIQUE: 중복 X
  - CHECK: 값 범위
  - FK: 참조 유효

비즈니스 규칙 (애플리케이션):
  - "잔액 < 출금액이면 거부"
  - 도메인 메서드
  - DB 제약 외

일관성 vs 무결성:
  - 무결성: 데이터 자체 (제약)
  - 일관성: 트랜잭션 후 상태 (더 넓음)

DB 의 감지:
  - 제약 위반 → 즉시 거부 (예외)
  - 전체 트랜잭션 rollback

→ Consistency = 트랜잭션 후 제약조건 + 비즈니스 규칙 항상 만족, 깨지면 rollback.


🧭 9개 섹션 로드맵

1. Consistency 정의
2. 제약조건 종류
3. 잔액 음수 불가 같은 제약
4. 자동 rollback
5. 일관성 vs 무결성
6. DB 의 감지 방식
7. 비즈니스 규칙
8. Spring/JPA 의 일관성
9. 면접 + 자기 점검

1️⃣ Consistency 정의

1.1 정의

Consistency (일관성):

  "트랜잭션 완료 후
   DB 제약조건이 항상 지켜져야"

  - 일관된 상태 유지
  - 모든 규칙 만족

1.2 시작/끝 모두 일관

시작/끝 모두 일관:

  트랜잭션 전: 일관 상태
  트랜잭션 후: 일관 상태

  (중간은 격리 — 외부 X)

→ 일관 → 일관 보장

1.3 "Valid State"

"Valid State":

  유효한 상태:
    - 모든 제약 만족
    - 비즈니스 규칙 만족
    - 의미 있는 데이터

→ 일관성 = 유효성

1.4 ILIC 의 맥락

Consistency (ILIC)

ILIC 일관성 예:
  - 배송 (Shipment) 은 예약 (Booking) 참조 필수 (FK)
  - 운임 (freight) ≥ 0 (CHECK)
  - BL 번호 (bl_no) 유일 (UNIQUE)
  - 상태 (status) 는 정해진 값만 (CHECK)

  트랜잭션 후:
    - 위 모두 만족
    - 깨지면 → rollback

→ DB 가 유효성 보장

1.5 자기 점검 답변

Consistency (일관성) 의 정의는?

:
1. 정의:

  • 제약조건 항상
  1. 시작/끝:

    • 일관 → 일관
  2. Valid State:

    • 유효한 상태
  3. 목적:

    • 의미 있는 데이터

2️⃣ 제약조건 종류

2.1 5가지 제약

DB 제약조건 (5종):

1. NOT NULL: 필수 값
2. UNIQUE: 중복 X
3. PRIMARY KEY: NOT NULL + UNIQUE
4. CHECK: 값 검사
5. FOREIGN KEY: 참조 무결성

2.2 NOT NULL

-- NOT NULL
CREATE TABLE shipments (
    id BIGINT PRIMARY KEY,
    bl_no VARCHAR(50) NOT NULL,   -- 필수
    weight DECIMAL(10,2)
);

INSERT INTO shipments (id, weight) VALUES (1, 100);
-- ❌ bl_no 빠짐 → 제약 위반 → rollback

2.3 UNIQUE

-- UNIQUE
CREATE TABLE shipments (
    id BIGINT PRIMARY KEY,
    bl_no VARCHAR(50) UNIQUE   -- 중복 X
);

INSERT INTO shipments VALUES (1, 'BL001');
INSERT INTO shipments VALUES (2, 'BL001');
-- ❌ 중복 → 제약 위반 → rollback

2.4 CHECK

-- CHECK (값 검사)
CREATE TABLE accounts (
    id BIGINT PRIMARY KEY,
    balance DECIMAL(15,2) CHECK (balance >= 0)   -- 음수 X
);

UPDATE accounts SET balance = -100 WHERE id = 1;
-- ❌ 음수 → CHECK 위반 → rollback

2.5 FOREIGN KEY

-- FOREIGN KEY (참조 무결성)
CREATE TABLE shipments (
    id BIGINT PRIMARY KEY,
    booking_id BIGINT,
    FOREIGN KEY (booking_id) REFERENCES bookings(id)
);

INSERT INTO shipments VALUES (1, 999);
-- ❌ bookings.id=999 없음 → FK 위반 → rollback

2.6 ILIC 의 맥락

-- ILIC 의 제약조건 (102 테이블)

CREATE TABLE bookings (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    bl_no VARCHAR(50) NOT NULL UNIQUE,        -- 필수, 유일
    status VARCHAR(20) NOT NULL 
        CHECK (status IN ('BOOKED','CONFIRMED','SHIPPED','CANCELLED')),
    weight DECIMAL(10,2) CHECK (weight > 0),  -- 양수만
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE shipments (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    booking_id BIGINT NOT NULL,
    FOREIGN KEY (booking_id) REFERENCES bookings(id)   -- 참조 무결성
);

-- 제약 위반 시도:
INSERT INTO shipments (booking_id) VALUES (999);
-- ❌ booking.id=999 없음 → FK 위반 → rollback

INSERT INTO bookings (bl_no, status, weight) VALUES ('BL001', 'INVALID', 100);
-- ❌ status='INVALID' → CHECK 위반 → rollback

2.7 자기 점검 답변

제약조건 종류 (NOT NULL/UNIQUE/CHECK/FK) 는?

:
1. 5종:

  • NOT NULL/UNIQUE/PK/CHECK/FK
  1. NOT NULL:

    • 필수 값
  2. CHECK:

    • 값 범위
  3. FK:

    • 참조 무결성

3️⃣ 잔액 음수 불가 같은 제약

3.1 도메인 제약

도메인 제약:

  비즈니스 규칙:
    - "계좌 잔액은 음수 X"
    - "재고는 음수 X"
    - "주문 수량 ≥ 1"

→ 도메인 의미

3.2 DB 로 표현 (CHECK)

-- DB 레벨 (CHECK)
CREATE TABLE accounts (
    id BIGINT PRIMARY KEY,
    balance DECIMAL(15,2) CHECK (balance >= 0)
);

-- 이체 시도
BEGIN;
UPDATE accounts SET balance = balance - 100000 WHERE id = 'A';
-- A 잔액 50000 이라면? balance = -50000
-- ❌ CHECK 위반 → 자동 rollback (트랜잭션 전체)
COMMIT;   -- 도달 못 함

3.3 애플리케이션 검증

// 애플리케이션 (사전 검증)
@Service
public class TransferService {
    @Transactional
    public void transfer(Long from, Long to, BigDecimal amount) {
        Account fromAcc = accountDao.get(from);
        
        // 비즈니스 검증
        if (fromAcc.getBalance().compareTo(amount) < 0) {
            throw new InsufficientBalanceException();
            // → rollback
        }
        
        accountDao.decrease(from, amount);
        accountDao.increase(to, amount);
    }
    AccountDao accountDao;
}
class Account { java.math.BigDecimal getBalance() { return null; } }
class InsufficientBalanceException extends RuntimeException {}
class AccountDao {
    Account get(Long id) { return null; }
    void decrease(Long id, java.math.BigDecimal a) {}
    void increase(Long id, java.math.BigDecimal a) {}
}

3.4 2중 방어

2중 방어:

  애플리케이션 검증:
    - 빠른 거부
    - 사용자 피드백

  DB CHECK:
    - 최종 방어
    - 우회 X

→ 둘 다 (안전)

3.5 ILIC 의 맥락

-- ILIC 비즈니스 제약 (DB 레벨)
CREATE TABLE warehouse_items (
    id BIGINT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    stock INT NOT NULL CHECK (stock >= 0),   -- 재고 음수 X
    price DECIMAL(15,2) CHECK (price > 0)    -- 가격 양수
);

CREATE TABLE freights (
    id BIGINT PRIMARY KEY,
    shipment_id BIGINT NOT NULL,
    amount DECIMAL(15,2) CHECK (amount >= 0)  -- 운임 음수 X
);

-- 시도
UPDATE warehouse_items SET stock = stock - 100 WHERE id = 1;
-- 재고 50 이라면 → -50 시도 → CHECK 위반 → rollback
// 애플리케이션 검증 (ILIC)
@Service
public class WarehouseService {
    @Transactional
    public void decreaseStock(Long itemId, int amount) {
        WarehouseItem item = warehouseDao.get(itemId);
        
        // 비즈니스 검증 (DB CHECK 전에)
        if (item.getStock() < amount) {
            throw new InsufficientStockException();   // 사용자 친화
        }
        
        warehouseDao.decrease(itemId, amount);
        // 만약 검증 빠뜨려도 DB CHECK 가 막음
    }
    WarehouseDao warehouseDao;
}
class WarehouseItem { int getStock() { return 0; } }
class InsufficientStockException extends RuntimeException {}
class WarehouseDao {
    WarehouseItem get(Long id) { return null; }
    void decrease(Long id, int n) {}
}

3.6 자기 점검 답변

잔액 음수 불가 같은 제약은?

:
1. 도메인 제약:

  • 비즈니스 규칙
  1. DB CHECK:

    • 자동 거부
  2. 애플리케이션:

    • 사전 검증
  3. 2중 방어:

    • 둘 다

4️⃣ 자동 rollback

4.1 자동 rollback

제약 위반 시:

  DB 자동 동작:
    1. 제약 위반 감지
    2. SQL 실행 거부
    3. 예외 발생 (SQLException)
    4. 트랜잭션 전체 rollback

→ 일관성 보장

4.2 예외 종류

예외 종류 (JDBC):

  - SQLIntegrityConstraintViolationException
  - UNIQUE 위반
  - CHECK 위반
  - NOT NULL 위반
  - FK 위반

→ 모두 IntegrityConstraintViolation

4.3 트랜잭션 전체 rollback

트랜잭션 전체 rollback:

  한 SQL 위반 → 전체 트랜잭션 무효:
    - 이미 실행된 SQL 도 취소
    - 원자성과 함께
    - 일관 상태로 복원

→ Atomicity 와 협력

4.4 Spring 처리

// Spring 자동 rollback
@Transactional
public void process() {
    // SQL 1: INSERT (성공)
    dao.add(...);
    
    // SQL 2: UPDATE — CHECK 위반!
    accountDao.set(id, BigDecimal.valueOf(-100));
    // → DataIntegrityViolationException (Spring 변환)
    // → 자동 rollback (SQL 1 도 취소)
}

4.5 ILIC 의 맥락

// 자동 rollback (ILIC)
@Service
public class BookingService {
    
    @Transactional
    public void createBooking(Booking b) {
        try {
            // SQL 1: Booking (성공)
            bookingDao.add(b);
            
            // SQL 2: Shipment (booking_id 잘못된 값 → FK 위반)
            Shipment s = new Shipment();
            s.setBookingId(999L);   // 존재 X
            shipmentDao.add(s);
            // ❌ FK 위반 → DataIntegrityViolationException
            
            // SQL 3: 도달 못 함
        } catch (DataIntegrityViolationException e) {
            // Spring 이 자동 rollback (Booking 도 취소)
            throw e;
        }
        // → DB 일관성 유지 (Booking 있는데 Shipment 없음 X)
    }
    BookingDao bookingDao;
    ShipmentDao shipmentDao;
}
class Booking {}
class Shipment { void setBookingId(Long id) {} }
class BookingDao { void add(Booking b) {} }
class ShipmentDao { void add(Shipment s) {} }
class DataIntegrityViolationException extends RuntimeException {}

4.6 자기 점검 답변

깨지는 트랜잭션은 자동 rollback 동작은?

:
1. 자동 동작:

  • 위반 → 거부 → rollback
  1. 예외:

    • IntegrityConstraintViolation
  2. 전체:

    • 트랜잭션 전부
  3. Spring:

    • DataIntegrityViolationException

5️⃣ 일관성 vs 무결성

5.1 비교

항목무결성 (Integrity)일관성 (Consistency)
범위데이터 자체트랜잭션 후 상태
표현DB 제약 (CHECK/FK 등)모든 규칙 (제약 + 비즈니스)
책임DBDB + 애플리케이션

5.2 무결성

무결성 (Integrity):

  데이터 정합성:
    - 개체 (Entity): PK
    - 참조 (Referential): FK
    - 도메인: CHECK/TYPE

  → DB 가 강제

5.3 일관성

일관성 (Consistency):

  더 넓은 개념:
    - 무결성 +
    - 비즈니스 규칙
    - 의미 있는 상태

  → DB + 애플리케이션

5.4 ACID 의 Consistency

ACID 의 Consistency:

  트랜잭션 후:
    - 무결성 보장 (DB)
    - 비즈니스 규칙 (애플리케이션 + DB CHECK)
    - 종합적 유효 상태

→ 무결성 ⊆ 일관성

5.5 ILIC 의 맥락

무결성 vs 일관성 (ILIC)

무결성 (DB 자동):
  - bookings.bl_no UNIQUE (개체 무결성)
  - shipments.booking_id REFERENCES (참조 무결성)
  - weight > 0 (도메인 무결성)

일관성 (DB + 애플리케이션):
  - 무결성 +
  - "예약 상태가 CANCELLED 면 배송 진행 X" (비즈니스)
  - "운임은 weight × rate" (계산 일관)
  - 도메인 규칙

→ DB 가 일부, 애플리케이션이 나머지
→ 둘 다 협력

5.6 자기 점검 답변

일관성 vs 무결성 (Integrity) 차이는?

:
1. 무결성:

  • 데이터 정합성
  1. 일관성:

    • 더 넓음
  2. 책임:

    • 무결성: DB
    • 일관성: DB + 앱
  3. 포함:

    • 무결성 ⊆ 일관성

6️⃣ DB 의 감지 방식

6.1 감지 시점

DB 의 감지 시점:

1. SQL 실행 시 (즉시)
   - NOT NULL: INSERT 시
   - UNIQUE: INSERT 시
   - CHECK: 값 변경 시
   - FK: 참조 변경 시

2. 트랜잭션 commit 시 (지연)
   - DEFERRABLE 옵션

6.2 즉시 감지

-- 즉시 감지 (기본)
BEGIN;
INSERT INTO bookings (bl_no) VALUES ('BL001');
INSERT INTO bookings (bl_no) VALUES ('BL001');
-- ↑ UNIQUE 위반 → 즉시 예외
-- 트랜잭션 rollback 표시
COMMIT;   -- 실패

6.3 인덱스 활용

인덱스 활용:

  UNIQUE: 유니크 인덱스
  PK: 클러스터 인덱스
  → 빠른 감지

  CHECK: 표현식 평가
  FK: 참조 테이블 조회

6.4 트리거

트리거 (Trigger):

  특정 이벤트 시 자동 실행:
    - BEFORE INSERT
    - 추가 검증
    - 일관성 강화

→ 제약 보완

6.5 ILIC 의 맥락

-- 감지 동작 (ILIC MySQL)

-- 1. NOT NULL 즉시 감지
INSERT INTO bookings (status) VALUES ('BOOKED');
-- ❌ bl_no NULL → "Column 'bl_no' cannot be null"

-- 2. UNIQUE 즉시 감지
INSERT INTO bookings (bl_no, status) VALUES ('BL001', 'BOOKED');
INSERT INTO bookings (bl_no, status) VALUES ('BL001', 'CONFIRMED');
-- ❌ "Duplicate entry 'BL001'"

-- 3. CHECK 감지
INSERT INTO accounts (id, balance) VALUES (1, -100);
-- ❌ "CHECK constraint 'accounts_chk' is violated"

-- 4. FK 감지
INSERT INTO shipments (booking_id) VALUES (999);
-- ❌ "Cannot add or update: foreign key constraint fails"

-- 모두 SQLException → Spring DataIntegrityViolationException

6.6 자기 점검 답변

DB 가 일관성을 감지하는 방식은?

:
1. 시점:

  • SQL 실행 시 (기본)
  1. 즉시:

    • 위반 즉시 예외
  2. 활용:

    • 인덱스/표현식/참조
  3. 트리거:

    • 추가 검증

7️⃣ 비즈니스 규칙

7.1 비즈니스 규칙

비즈니스 규칙:

  도메인 의미:
    - "예약은 결제 후"
    - "회원만 주문"
    - "재고 ≤ 주문 거부"

→ DB 제약 외

7.2 어디서 강제

어디서 강제:

  애플리케이션 (주로):
    - 도메인 로직
    - Service 메서드
    - 명확한 메시지

  DB (보조):
    - CHECK
    - TRIGGER

7.3 도메인 메서드

// 도메인 메서드로 일관성
public class Account {
    private BigDecimal balance;
    
    public void withdraw(BigDecimal amount) {
        // 도메인 규칙
        if (balance.compareTo(amount) < 0) {
            throw new InsufficientBalanceException();
        }
        balance = balance.subtract(amount);
    }
    // 잔액 음수 불가 도메인이 보장
}
class InsufficientBalanceException extends RuntimeException {}

7.4 DB 만으로 부족

DB 만으로 부족:

  복잡한 규칙:
    - "월 한도 초과 X"
    - "VIP 만 할인"
    - "거래 시간 외 X"

  → 애플리케이션 (도메인 로직)

7.5 ILIC 의 맥락

// 비즈니스 규칙 (ILIC)
@Service
public class BookingService {
    
    @Transactional
    public void createBooking(BookingRequest req) {
        // 비즈니스 규칙 1: 회원만 예약
        Customer customer = customerDao.get(req.getCustomerId());
        if (!customer.isActive()) {
            throw new IllegalStateException("비활성 회원");
        }
        
        // 비즈니스 규칙 2: 거래 한도
        BigDecimal monthlyTotal = bookingDao.sumMonthly(customer.getId());
        if (monthlyTotal.add(req.getAmount())
                .compareTo(customer.getMonthlyLimit()) > 0) {
            throw new IllegalStateException("월 한도 초과");
        }
        
        // 비즈니스 규칙 3: 상품 재고
        if (warehouseDao.getStock(req.getItemId()) < req.getQuantity()) {
            throw new IllegalStateException("재고 부족");
        }
        
        // 예약 진행
        bookingDao.add(req.toBooking());
        warehouseDao.decreaseStock(req.getItemId(), req.getQuantity());
        // DB CHECK 도 추가 방어
    }
    CustomerDao customerDao;
    BookingDao bookingDao;
    WarehouseDao warehouseDao;
}
class BookingRequest {
    Long getCustomerId() { return null; }
    Long getItemId() { return null; }
    int getQuantity() { return 0; }
    java.math.BigDecimal getAmount() { return null; }
    Booking toBooking() { return null; }
}
class Booking {}
class Customer {
    Long getId() { return null; }
    boolean isActive() { return false; }
    java.math.BigDecimal getMonthlyLimit() { return null; }
}
class CustomerDao { Customer get(Long id) { return null; } }
class BookingDao {
    void add(Booking b) {}
    java.math.BigDecimal sumMonthly(Long id) { return null; }
}
class WarehouseDao {
    int getStock(Long id) { return 0; }
    void decreaseStock(Long id, int n) {}
}

7.6 자기 점검 답변

비즈니스 규칙은 어디서 강제하나?

:
1. 비즈니스 규칙:

  • 도메인 의미
  1. 애플리케이션:

    • 주 강제
  2. DB:

    • 보조 (CHECK)
  3. 도메인 메서드:

    • 캡슐화

8️⃣ Spring/JPA 의 일관성

8.1 JPA 의 도움

JPA 의 도움:

  엔티티 검증:
    - @NotNull
    - @Size
    - @Min/@Max
    - @AssertTrue
    - 등 Bean Validation

  → 애플리케이션 일관성

8.2 Bean Validation

// JPA + Bean Validation
@Entity
@Table(name = "bookings")
public class Booking {
    @Id
    @GeneratedValue
    private Long id;
    
    @NotNull
    @Size(min = 1, max = 50)
    private String blNo;
    
    @NotNull
    @Min(0)
    private BigDecimal weight;
    
    @NotNull
    @Pattern(regexp = "BOOKED|CONFIRMED|SHIPPED|CANCELLED")
    private String status;
    // 저장 시 검증
}

8.3 @Valid 트리거

// Controller 검증
@RestController
public class BookingController {
    
    @PostMapping("/api/bookings")
    public Booking create(@Valid @RequestBody BookingRequest req) {
        // @Valid → Bean Validation 실행
        // 위반 시 → MethodArgumentNotValidException
        return null;
    }
}
class BookingRequest {}

8.4 라이프사이클 콜백

// JPA 라이프사이클
@Entity
public class Booking {
    @PrePersist
    void prePersist() {
        // 저장 전 검증
        if (status == null) {
            status = "BOOKED";   // 기본값
        }
        // 추가 비즈니스 일관성
    }
    
    @PreUpdate
    void preUpdate() {
        // 수정 전 검증
    }
    String status;
}

8.5 ILIC 의 맥락

// Spring/JPA 일관성 (ILIC)

// 엔티티 (Bean Validation)
@Entity
@Table(name = "shipments")
public class Shipment {
    @Id @GeneratedValue
    private Long id;
    
    @NotNull
    @Size(min = 1, max = 50)
    private String blNo;
    
    @NotNull @DecimalMin("0.0")
    private BigDecimal weight;
    
    @NotNull @ManyToOne
    private Booking booking;   // FK
    
    @PrePersist
    void onPrePersist() {
        // 비즈니스 일관성
        if (this.status == null) {
            this.status = "BOOKED";
        }
    }
    private String status;
}

// Service
@Service
public class ShipmentService {
    @Transactional
    public void create(@Valid Shipment s) {   // Bean Validation
        // 검증 통과 후 저장
        shipmentRepository.save(s);
        // JPA → SQL → DB CHECK
        // 다중 방어
    }
    ShipmentRepository shipmentRepository;
}
interface ShipmentRepository { void save(Shipment s); }
class Booking {}

8.6 자기 점검 답변

Spring/JPA 의 일관성 처리는?

:
1. JPA:

  • Bean Validation
  1. @NotNull/@Size:

    • 엔티티 제약
  2. @Valid:

    • Controller 검증
  3. @PrePersist:

    • 라이프사이클

9️⃣ 면접 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
Consistency?제약조건 항상
제약조건?NOT NULL/UNIQUE/CHECK/FK
잔액 음수?CHECK 또는 도메인
자동 rollback?제약 위반 시
vs 무결성?일관성 더 넓음
DB 감지?SQL 실행 시
비즈니스 규칙?애플리케이션
Spring?Bean Validation
JPA?@NotNull 등
다중 방어?DB + 앱

9.2 자기 점검 체크리스트

정의

  • 제약조건 항상

제약

  • 5종

잔액

  • CHECK

자동

  • rollback

vs 무결성

  • 넓음

감지

  • SQL 시

비즈니스

  • 애플리케이션

Spring/JPA

  • Bean Validation

9.3 추가 심화 질문

Q1: 일관성과 분산?

답:

  • 단일 DB: 강한 일관성
  • 분산: 약한 일관성 (eventual)
  • CAP 정리
  • 트레이드오프

Q2: 외래 키 vs 애플리케이션 참조 검증?

답:

  • FK: DB 가 강제 (안전)
  • 애플리케이션: 더 풍부한 메시지
  • 둘 다 (보통)
  • MSA 는 FK 없는 경우 (DB 분리)

Q3: CASCADE?

답:

  • FK 옵션
  • ON DELETE CASCADE
  • 부모 삭제 → 자식 자동 삭제
  • 일관성 자동 유지

Q4: 일관성과 성능?

답:

  • 제약 검증 비용
  • 인덱스 (UNIQUE)
  • FK 락
  • 일부 성능 ↓ (안전 ↑)

Q5: NoSQL 의 일관성?

답:

  • 약한 일관성 (대부분)
  • eventual consistency
  • 분산 우선
  • 트레이드오프

🎯 핵심 요약 — 3줄 정리

1. Consistency (일관성)

  • 트랜잭션 완료 후 DB 가 항상 일관된 상태 (제약조건 만족)
  • NOT NULL / UNIQUE / CHECK / FOREIGN KEY 등

2. 자동 rollback

  • 제약 위반 시 DB 가 자동으로 전체 트랜잭션 rollback
  • IntegrityConstraintViolationException

3. 책임 분담

  • DB 제약: 무결성 (필수, 자동)
  • 비즈니스 규칙: 애플리케이션 (도메인 메서드/Bean Validation)
  • 다중 방어 (DB + 앱)

📚 다음으로...

Unit 6.4 — Isolation (격리성) ★깊이

이번 Unit에서 Consistency 를 봤다면, 다음은 Isolation (★ 깊이 파기).

  • 트랜잭션 독립 실행
  • 격리 수준 4가지
  • Dirty Read, Phantom Read
  • 동시성 vs 일관성

Phase 6 진행 상황

💎 Phase 6 — 트랜잭션과 ACID
  ✅ Unit 6.1 트랜잭션이란
  ✅ Unit 6.2 Atomicity ★깊이
  ✅ Unit 6.3 Consistency ★깊이 ← 여기
  ⏭ Unit 6.4 Isolation ★깊이
  ⏭ Unit 6.5 Durability ★깊이
  ⏭ Unit 6.6 Commit 이전 동시성 ★깊이

6주차 누적 진행

🧪 Part A (9 Unit) ✅
💾 Part B — DB 접근의 진화
  ✅ Phase 3 — JDBC (3)
  ✅ Phase 4 — Connection Pool (4)
  ✅ Phase 5 — DataSource (4)
  💎 Phase 6 — ACID (3/6)

총: 23/28 Unit

★ 깊이 파기 — Consistency 완료

profile
Software Developer

0개의 댓글