소프트웨어 기술(스타트업 위주)
컴퓨터구조
컴퓨터구조 정리 입니다.
데이터베이스 개념 (Database Concepts)
1. 데이터베이스 정의 (Database Definition)
- 조직화된 데이터의 모음
- 효율적인 데이터 저장, 검색, 수정을 위한 구조화된 시스템
- 데이터의 중복을 최소화하고 일관성을 유지하는 메커니즘
1.1 정규화 (Normalization)
정의 (Definition)
데이터베이스의 구조를 일관성 있게 조직화하는 과정
데이터 중복성을 제거하고 데이터 무결성을 향상시키는 기술
각 테이블의 의존성을 최소화하여 데이터 이상 현상을 방지
정규화 형태 (Normalization Forms)
1차 정규화 (1NF)
- 각 행과 열이 고유한 값을 가짐
- 반복되는 그룹을 제거
- 각 셀이 원자값을 가짐
2차 정규화 (2NF)
- 1NF를 만족
- 부분 종속 제거
- 복합 키가 있는 테이블의 비주요 속성 제거
부분 종속이란, 복합 기본키의 일부에만 종속된 속성을 의미합니다.
- 복합키란 기본키가 두 개 이상의 속성으로 이루어진 경우, 이 중 일부 키에만 의존하는 속성이 있으면 부분 종속
예시
학번 | 과목코드 | 성적 | 학생이름 |
---|---|---|---|
202301 | MATH101 | 90 | 김철수 |
202301 | ENG102 | 85 | 김철수 |
202302 | MATH101 | 78 | 이영희 |
- 기본키:
(학번, 과목코드)
성적
은(학번, 과목코드)
전체에 종속 → 정상 종속학생이름
은학번
에만 종속 → 부분 종속
문제점
- 중복 데이터 발생 (과목이 다르면 이름도 반복 저장됨)
- 데이터 수정 및 관리의 어려움
- 저장 공간 낭비
해결 방법: 제2정규형 (2NF)
부분 종속 제거 → 테이블 분리
정규화 예
- 학생 테이블
학번 | 학생이름 |
---|---|
202301 | 김철수 |
202302 | 이영희 |
- 성적 테이블
학번 | 과목코드 | 성적 |
---|---|---|
202301 | MATH101 | 90 |
202301 | ENG102 | 85 |
202302 | MATH101 | 78 |
- 3차 정규화
제3정규형 (3NF) 은 제2정규형을 만족하면서,
이행적 종속(Transitive Dependency) 을 제거한 정규형이다.
이행적 종속:
A → B, B → C 일 때 A → C가 되는 상황제3정규형은 이런 중간 단계(B)가 존재하는 종속 관계를 제거하는 것
예시
학번 | 학생이름 | 학과코드 | 학과이름 |
---|---|---|---|
202301 | 김철수 | CSE | 컴퓨터공학과 |
202302 | 이영희 | ENG | 영어영문학과 |
- 기본키:
학번
학생이름
은학번
에 직접 종속 → OK학과이름
은학과코드
에 종속,학과코드
는학번
에 종속
즉, 학번 → 학과코드 → 학과이름
이행적 종속 발생
문제점
- 학과코드가 바뀌면 모든 학생 행을 수정해야 함
- 데이터 중복
- 수정 이상(anomaly) 발생 가능
이행적 종속을 제거 → 테이블 분리
학생 테이블
학번 | 학생이름 | 학과코드 |
---|---|---|
202301 | 김철수 | CSE |
202302 | 이영희 | ENG |
학과 테이블
학과코드 | 학과이름 |
---|---|
CSE | 컴퓨터공학과 |
ENG | 영어영문학과 |
1.2 비정규화 (Denormalization)
정의 (Definition)
- 의도적으로 데이터 중복을 허용하여 성능을 향상시키는 기술
- 조인 연산을 줄이고 데이터 조회 성능을 개선하는 방법
구현 방법 (Implementation Methods)
- 중복 데이터 저장
-- 정규화된 구조
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE
);
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100)
);
-- 비정규화된 구조
CREATE TABLE orders_denormalized (
order_id INT PRIMARY KEY,
customer_id INT,
customer_name VARCHAR(100),
customer_email VARCHAR(100),
order_date DATE
);
- 요약 테이블 사용
CREATE TABLE daily_sales_summary (
date DATE,
total_sales DECIMAL(10,2),
product_count INT,
customer_count INT
);
1.3 관계형 데이터베이스 (Relational Databases)
정의 (Definition)
테이블 형태로 데이터를 저장하고 관리하는 데이터베이스 시스템
SQL을 사용하여 데이터를 조작하고 조회
엔티티 간의 관계를 명확하게 정의 가능
특징 (Characteristics)
테이블 기반 구조
관계 정의 가능
SQL 지원
데이터 무결성 보장
표준화된 쿼리 언어
장단점 (Advantages and Limitations)
장점 (Advantages) | 단점 (Disadvantages) |
---|---|
1. 데이터 무결성 강화 | 1. 유연성 제한 |
2. 표준화된 쿼리 언어 | 2. 확장성 제한 |
3. 트랜잭션 지원 | 3. 복잡한 데이터 구조 부적합 |
4. 데이터 일관성 보장 | 4. 높은 학습 곡선 |
1.4 엔티티-관계 모델 (Entity-Relationship Model)
기본 개념 (Basic Concepts)
- 엔티티 (Entity): 독립적으로 존재하는 객체
- 속성 (Attribute): 엔티티의 특성
- 관계 (Relationship): 엔티티 간의 연결
관계 유형 (Relationship Types)
- 일대일 (One-to-One)
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE customer_details (
customer_id INT PRIMARY KEY,
address VARCHAR(200),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
- 일대다 (One-to-Many)
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
- 다대다 (Many-to-Many)
CREATE TABLE order_items (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(order_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
1.5 SQL vs NoSQL 데이터베이스
SQL 데이터베이스
- 정해진 스키마 필요
- 관계형 데이터 모델
- ACID 준수
- 표준화된 쿼리 언어
NoSQL 데이터베이스
- 유연한 스키마
- 다양한 데이터 모델
- BASE 준수
- 고성능 읽기/쓰기
비교 (Comparison)
특성 (Feature) | SQL | NoSQL |
---|---|---|
스키마 (Schema) | 고정형 | 유연형 |
데이터 모델 | 테이블 기반 | 다양한 모델 |
스케일링 | 수직적 | 수평적 |
쿼리 언어 | 표준화됨 | 다양함 |
트랜잭션 | ACID 지원 | 부분적 지원 |
1.6 락(Locking) 시스템
정의 (Definition)
- 데이터베이스에서 데이터 접근을 제어하기 위한 메커니즘
- 여러 트랜잭션이 동시에 데이터를 접근할 때 충돌을 방지하는 방법
특성 (Characteristics)
종류 (Types)
- 공유 락 (Shared Lock): 읽기 작업을 위한 락
- 배타 락 (Exclusive Lock): 쓰기 작업을 위한 락
- 업데이트 락 (Update Lock): 데이터를 업데이트하기 전에 사용
특징 (Features)
- 트랜잭션 간의 데이터 일관성 보장
- 데이터 접근 순서 제어
- 동시성 제어를 위한 기본 메커니즘
주의사항 (Precautions)
- 데드락 발생 가능성
- 성능 저하 가능성
- 적절한 락 수준 선택 필요
구현 예시 (Implementation Example)
-- 트랜잭션 시작
BEGIN TRANSACTION;
-- 공유 락 획득
SELECT * FROM employees WHERE department_id = 1 LOCK IN SHARE MODE;
-- 배타 락 획득
SELECT * FROM employees WHERE department_id = 1 FOR UPDATE;
-- 트랜잭션 커밋
COMMIT;
1.7 ACID 모델 (ACID Model)
정의 (Definition)
- 데이터베이스 트랜잭션의 신뢰성을 보장하는 네 가지 속성의 집합
- Atomicity, Consistency, Isolation, Durability의 약자
특성 (Characteristics)
원자성 (Atomicity)
- 트랜잭션이 완전히 성공하거나 완전히 실패
- 부분적인 실행 불가능
일관성 (Consistency)
- 트랜잭션 전후 데이터베이스 상태가 유효해야 함
- 데이터 무결성 제약 조건 준수
독립성 (Isolation)
- 트랜잭션 간의 영향이 없어야 함
- 격리 수준에 따라 다름
영속성 (Durability)
- 커밋된 트랜잭션의 결과는 영구적
- 시스템 장애에도 데이터 유지
구현 예시 (Implementation Example)
-- 트랜잭션 시작
BEGIN TRANSACTION;
-- 원자성 보장
SAVEPOINT my_savepoint;
INSERT INTO accounts (id, balance) VALUES (1, 1000);
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- 오류 발생 시 롤백
IF error THEN
ROLLBACK TO SAVEPOINT my_savepoint;
END IF;
-- 트랜잭션 커밋
COMMIT;
2. 기본 SQL 구문 (Basic SQL Syntax)
SELECT 문
SELECT column1, column2
FROM table_name
WHERE condition
GROUP BY column_name
HAVING group_condition
ORDER BY column_name
LIMIT number;
INSERT 문
INSERT INTO table_name (column1, column2)
VALUES (value1, value2);
UPDATE 문
UPDATE table_name
SET column1 = value1, column2 = value2
WHERE condition;
DELETE 문
DELETE FROM table_name
WHERE condition;
3. SQL 키워드 (SQL Keywords)
데이터 정의 (DDL)
- CREATE: 테이블 생성
- ALTER: 테이블 수정
- DROP: 테이블 삭제
- TRUNCATE: 테이블 초기화
데이터 조작 (DML)
- INSERT: 데이터 삽입
- UPDATE: 데이터 수정
- DELETE: 데이터 삭제
- SELECT: 데이터 조회
제약 조건 (Constraints)
- PRIMARY KEY: 기본 키
- FOREIGN KEY: 외래 키
- UNIQUE: 고유성 제약
- NOT NULL: 널 금지
- CHECK: 데이터 유효성 검사
데이터 타입 (Data Types)
숫자형 (Numeric)
- INT: 정수
- DECIMAL: 소수점
- FLOAT: 부동소수점
문자형 (Character)
- CHAR: 고정 길이 문자열
- VARCHAR: 가변 길이 문자열
- TEXT: 긴 텍스트
날짜/시간형 (Date/Time)
- DATE: 날짜
- TIME: 시간
- TIMESTAMP: 타임스탬프
이진형 (Binary)
- BINARY: 이진 데이터
- BLOB: 큰 이진 객체
연산자 (Operators)
비교 연산자 (Comparison)
- =: 같음
- !=, <>: 다름
, <: 크기 비교
=, <=: 크기 비교
- BETWEEN: 범위 비교
- IN: 목록 비교
- LIKE: 패턴 비교
- IS NULL: 널 비교
논리 연산자 (Logical)
- AND: 논리곱
- OR: 논리합
- NOT: 부정
집계 연산자 (Aggregate)
- SUM: 합계
- COUNT: 개수
- AVG: 평균
- MAX: 최대값
- MIN: 최소값
문자열 연산자 (String)
- CONCAT: 문자열 결합
- LENGTH: 길이
- UPPER: 대문자
- LOWER: 소문자
- SUBSTRING: 부분 문자열
날짜/시간 연산자 (Date/Time)
- DATEADD: 날짜/시간 추가
- DATEDIFF: 날짜/시간 차이
- DATEPART: 날짜/시간 부분 추출
이 문서는 데이터베이스의 동시성 제어와 모델, SQL 기본 문법에 대해 상세히 설명하고 있습니다. 각 섹션은 실제 예시와 함께 제공되어 실무에서 바로 적용할 수 있도록 구성되었습니다.
4. 데이터 정의 언어 (Data Definition Language)
CREATE TABLE
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
department_id INT,
FOREIGN KEY (department_id) REFERENCES departments(department_id)
);
ALTER TABLE
ALTER TABLE employees
ADD COLUMN phone VARCHAR(20);
ALTER TABLE employees
MODIFY COLUMN salary DECIMAL(10,2);
ALTER TABLE employees
DROP COLUMN temporary_field;
DROP TABLE
DROP TABLE employees;
-- 안전하게 삭제하기
DROP TABLE IF EXISTS employees;
TRUNCATE TABLE
TRUNCATE TABLE employees;
5. 데이터 조작 언어 (Data Manipulation Language)
SELECT
SELECT *
FROM employees
WHERE department_id = 1
AND salary > 50000
ORDER BY name ASC
LIMIT 10;
INSERT
INSERT INTO employees (employee_id, name, email)
VALUES (1, 'John Doe', 'john@example.com');
UPDATE
UPDATE employees
SET salary = salary * 1.1,
last_updated = CURRENT_TIMESTAMP
WHERE department_id = 1;
DELETE
DELETE FROM employees
WHERE employee_id = 1;
6. 집계 쿼리 (Aggregate Queries)
-- 그룹화와 집계
SELECT department_id,
COUNT(*) as employee_count,
AVG(salary) as avg_salary,
MAX(salary) as max_salary,
MIN(salary) as min_salary
FROM employees
GROUP BY department_id
HAVING avg_salary > 60000;
7. 데이터 제약조건 (Data Constraints)
PRIMARY KEY
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100)
);
FOREIGN KEY
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
UNIQUE
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
email VARCHAR(100) UNIQUE
);
NOT NULL
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
CHECK
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
salary DECIMAL(10,2) CHECK (salary > 0)
);
8. JOIN 쿼리 (JOIN Queries)
INNER JOIN
SELECT *
FROM employees
INNER JOIN departments
ON employees.department_id = departments.department_id;
LEFT JOIN
SELECT *
FROM employees
LEFT JOIN departments
ON employees.department_id = departments.department_id;
RIGHT JOIN
SELECT *
FROM employees
RIGHT JOIN departments
ON employees.department_id = departments.department_id;
FULL OUTER JOIN
SELECT *
FROM employees
FULL OUTER JOIN departments
ON employees.department_id = departments.department_id;
9. 서브쿼리 (Subqueries)
중첩 서브쿼리 (Nested Subquery)
SELECT *
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
상관 서브쿼리 (Correlated Subquery)
SELECT department_id, employee_id, salary
FROM employees e1
WHERE salary > (
SELECT AVG(salary)
FROM employees e2
WHERE e2.department_id = e1.department_id
);
10. 고급 함수 (Advanced Functions)
문자열 함수 (String Functions)
SELECT
CONCAT(first_name, ' ', last_name) as full_name,
LENGTH(email) as email_length,
UPPER(email) as email_upper,
LOWER(email) as email_lower,
SUBSTRING(email, 1, INSTR(email, '@') - 1) as username
FROM employees;
날짜/시간 함수 (Date/Time Functions)
SELECT
CURDATE() AS today,
NOW() AS now,
DATE_ADD(hire_date, INTERVAL 30 DAY) AS future_date,
TIMESTAMPDIFF(YEAR, hire_date, CURDATE()) AS years_of_service
FROM employees;
11. 뷰 (Views)
뷰 생성 (Creating Views)
CREATE VIEW employee_department AS
SELECT e.employee_id, e.name, d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id;
뷰 수정 (Modifying Views)
CREATE OR REPLACE VIEW employee_department AS
SELECT e.employee_id, e.name, d.department_name,
e.salary * 1.1 as new_salary
FROM employees e
JOIN departments d ON e.department_id = d.department_id;
뷰 삭제 (Dropping Views)
DROP VIEW employee_department;
12. 인덱스 (Indexes)
인덱스 생성 (Creating Indexes)
CREATE INDEX idx_employee_name
ON employees(name);
CREATE UNIQUE INDEX idx_employee_email
ON employees(email);
CREATE INDEX idx_employee_salary_dept
ON employees(salary, department_id);
13. 트랜잭션 (Transactions)
ACID 속성 (ACID Properties)
- 원자성 (Atomicity): 트랜잭션이 완전히 성공하거나 완전히 실패
- 일관성 (Consistency): 데이터베이스 상태가 항상 유효
- 독립성 (Isolation): 트랜잭션이 독립적으로 실행
- 영속성 (Durability): 커밋된 트랜잭션은 영구적
트랜잭션 격리 수준 (Transaction Isolation Levels)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRANSACTION;
-- 트랜잭션 작업
INSERT INTO accounts (id, balance) VALUES (1, 1000);
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
14. 데이터 무결성 및 보안 (Data Integrity & Security)
데이터 무결성 제약조건 (Data Integrity Constraints)
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
salary DECIMAL(10,2) CHECK (salary > 0)
);
권한 관리 (Access Control)
GRANT SELECT, INSERT ON employees TO 'user'@'localhost';
REVOKE UPDATE ON employees FROM 'user'@'localhost';
15. 데이터베이스 백업 (Database Backup)
백업 방법
- SELECT INTO: 기존 데이터를 새로운 테이블로 복사
SELECT * INTO BackupTable FROM OriginalTable;
- INSERT INTO + SELECT: 기존 테이블에 데이터를 추가 복사
INSERT INTO BackupTable SELECT * FROM OriginalTable;
- 데이터베이스 전체 백업 (MS SQL Server)
BACKUP DATABASE mydb TO DISK = 'C:\backup\mydb.bak';
- MySQL 데이터 덤프
mysqldump -u root -p mydb > mydb_backup.sql
데이터 복구 방법
- 삭제된 데이터 복구
- 백업 테이블이 존재하는 경우:
INSERT INTO OriginalTable SELECT * FROM BackupTable;
TRANSACTION
을 사용하여 롤백:BEGIN TRANSACTION; DELETE FROM Users WHERE UserID = 1; ROLLBACK;
- MySQL 데이터 복구
mysql -u root -p mydb < mydb_backup.sql
- 백업 테이블이 존재하는 경우:
16. 성능 최적화 (Performance Optimization)
EXPLAIN / EXPLAIN PLAN을 활용한 성능 최적화
EXPLAIN 사용법
쿼리 실행 계획을 확인하여 성능을 분석하는 도구
EXPLAIN SELECT *
FROM employees
WHERE department_id = 1
AND salary > 50000;
- 주요 분석 지표
항목 | 설명 |
---|---|
id | 실행되는 쿼리의 순서 |
select_type | SELECT 문 유형 |
table | 조회하는 테이블 |
type | 조인 방식 (ALL, INDEX, RANGE, REF, EQ_REF, CONST, SYSTEM) |
possible_keys | 사용 가능한 인덱스 |
key | 실제 사용된 인덱스 |
rows | 조회할 예상 행 개수 |
성능 최적화 방법
- 인덱스 활용:
EXPLAIN
결과에서possible_keys
에 적절한 인덱스가 있는지 확인CREATE INDEX idx_users_age ON Users(Age);
- 불필요한 서브쿼리 제거
→ 서브쿼리를SELECT * FROM Users WHERE Age IN (SELECT Age FROM Employees);
JOIN
으로 변경하여 최적화SELECT Users.* FROM Users INNER JOIN Employees ON Users.Age = Employees.Age;
- SELECT 최적화 (필요한 컬럼만 조회)
SELECT Name, Age FROM Users;
인덱스 최적화 (Index Optimization)
CREATE INDEX idx_employee_dept_salary
ON employees(department_id, salary);
-- 인덱스 통계 업데이트
ANALYZE TABLE employees;
조인 최적화 (Join Optimization)
-- 인덱스를 활용한 조인
SELECT /*+ USE_NL(e d) */
e.*, d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE e.department_id = 1;
17. 데이터베이스 링크 (DBLINK)
-> mysql 에서는 federated 사용
CREATE DATABASE LINK remote_db
CONNECT TO username IDENTIFIED BY password
USING 'remote_database';
SELECT *
FROM employees@remote_db;
18. 저장 프로시저와 함수 (Stored Procedures & Functions)
CREATE PROCEDURE update_employee_salary(
IN p_employee_id INT,
IN p_salary_increase DECIMAL(10,2)
)
BEGIN
UPDATE employees
SET salary = salary + p_salary_increase
WHERE employee_id = p_employee_id;
END;
19. MySQL 트랜잭션 격리 수준 (Isolation Level)
개념 정리
트랜잭션 격리 수준(Isolation Level)은 여러 트랜잭션이 동시에 실행될 때, 데이터의 정합성을 어떻게 보장할지를 결정하는 설정 값입니다.
MySQL에서는 4단계의 격리 수준을 제공하며, 각각은 데이터 정합성과 성능의 균형을 조절합니다.
트랜잭션 간 발생할 수 있는 문제
현상 | 설명 |
---|---|
Dirty Read | 다른 트랜잭션이 아직 커밋하지 않은 값을 읽는 것 |
Non-Repeatable Read | 같은 쿼리를 두 번 실행했을 때 값이 바뀌는 현상 |
Phantom Read | 같은 조건으로 두 번 조회했을 때 처음엔 없던 행이 새로 생김 |
MySQL Isolation Level 종류
격리 수준 | 설명 | 방지되는 문제 | 성능 |
---|---|---|---|
READ UNCOMMITTED | 커밋되지 않은 데이터도 읽을 수 있음 (가장 낮은 수준) | 없음 | 매우 빠름 |
READ COMMITTED | 커밋된 데이터만 읽을 수 있음 | Dirty Read 방지 | 빠름 |
REPEATABLE READ | 같은 쿼리를 반복해도 항상 같은 결과 (MySQL 기본값) | Dirty Read, Non-Repeatable Read 방지 | 중간 |
SERIALIZABLE | 모든 트랜잭션을 순차적으로 실행 (가장 높은 정합성) | 모든 문제 방지 | 느림 (동시성 낮음) |
기본 격리 수준 확인 및 설정
-- 현재 세션의 격리 수준 확인
SELECT @@transaction_isolation;
-- 세션 수준 격리 설정 (1회성)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 글로벌(서버 전체) 격리 설정 (영구 적용은 my.cnf 수정 필요)
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
실제 현업 예시
작업 예시 | 추천 격리 수준 | 이유 |
---|---|---|
게시글 목록 조회, 상품 리스트 조회 | READ COMMITTED | 커밋된 데이터만 보이면 충분하며 성능도 좋음 |
사용자 포인트/잔액 확인 후 차감 | REPEATABLE READ | 조회 시점 기준으로 값이 유지되어야 함 (동시 차감 방지) |
계좌 이체, 결제, 재고 감소 | SERIALIZABLE | 완전한 정합성 보장 필요. 동시성보다 정확성이 우선 |
로그 분석, 실시간 대시보드 | READ UNCOMMITTED | 실시간성이 중요하고, 정합성은 크게 중요하지 않음 |
요약
- MySQL의 기본 격리 수준은
REPEATABLE READ
- 격리 수준이 높을수록 정합성은 올라가지만, 동시성/성능은 낮아짐
- 상황에 맞게
SESSION
단위로 조절해 사용하는 것이 실무에서는 일반적임
-- 격리 수준 변경 후 트랜잭션 예시
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
-- 쿼리 실행
COMMIT;
트랜잭션이 길어지면 락 경쟁, 데드락(deadlock) 문제가 발생할 수 있으므로 꼭 필요한 경우에만 격리 수준을 높이세요.
20. 트랜잭션과 락
20.1 비관적 락 (Pessimistic Lock)
"다른 사용자가 데이터를 수정할 수도 있으니, 먼저 잠궈놓자"
특징
- 데이터를 읽는 순간부터 락을 걸고, 다른 트랜잭션의 읽기/쓰기 차단
- 충돌 가능성이 높을 때 사용
- MySQL 등에서는
SELECT ... FOR UPDATE
문법 사용
예시
START TRANSACTION;
SELECT * FROM orders WHERE id = 1 FOR UPDATE;
UPDATE orders SET status = 'paid' WHERE id = 1;
COMMIT;
장단점
장점 | 단점 |
---|---|
충돌 확률 낮음 | 락으로 인한 병목 발생 가능 |
정합성 보장 우수 | 데드락 가능성 있음 |
20.2 낙관적 락 (Optimistic Lock)
"충돌은 잘 안 일어나니까, 나중에만 확인하자"
특징
- 읽을 땐 락 없이 자유롭게 사용
- 저장/수정 시 버전이나 수정일 기준으로 충돌 여부 검증
- 일반적으로
version
컬럼을 사용하여 비교
예시
-- 데이터 조회 시 version도 함께 조회
SELECT id, stock, version FROM products WHERE id = 1;
-- 갱신 시 version 일치 여부 확인
UPDATE products
SET stock = stock - 1, version = version + 1
WHERE id = 1 AND version = 3;
장단점
장점 | 단점 |
---|---|
락 없이 성능 우수 | 충돌 발생 시 재시도 로직 필요 |
데드락 없음 | 구현 복잡도 증가 |
20.3 실무 적용 예시
재고 차감
- 동시 주문 발생 시 재고 마이너스를 막기 위해 락 사용
- 비관적 락:
FOR UPDATE
- 낙관적 락:
version
필드 활용
마일리지 적립/차감
- 동시 적립/차감으로 인한 정합성 문제 예방
- 트랜잭션 + 락으로 안정성 확보
언제 어떤 락을 쓸까?
상황 | 추천 방식 |
---|---|
동시성 낮고 충돌 적음 | 낙관적 락 |
동시성 높고 충돌 많음 | 비관적 락 |
데이터 정합성 중요 | 비관적 락 |
대규모 읽기 중심 시스템 | 낙관적 락 |
요약
- 비관적 락: 데이터를 아예 잠궈서 충돌 방지 (
FOR UPDATE
) - 낙관적 락: 버전 체크를 통해 최종 커밋 시점에 충돌 확인
- 둘 다 트랜잭션 내부에서 동시성 제어를 위해 사용됨