데이터베이스 트랜잭션과 보안 완벽 가이드
DB를 다룸에 있어서 트랜잭션은 꼭 알아야 하는 필수 개념입니다!
1. 트랜잭션이란 무엇인가?
트랜잭션은 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미합니다.
실생활 예시: 계좌이체
호날두가 메시에게 100만원을 송금하는 상황을 생각해보세요:
1호날두의 계좌에서 100만원을 차감합니다.
2메시의 계좌에다가 100만원을 더합니다.
만약 1단계는 성공했는데 2단계에서 오류가 발생한다면? 호날두의 100만원은 어디로 갔을까요? 이런 문제를 방지하기 위해 트랜잭션 개념이 필요합니다.
• 커밋(Commit): 모든 작업이 성공적으로 완료되어 반영되는 것
• 롤백(Rollback): 문제가 하나라도 발생하여 원래 상태로 돌아가는 것
MySQL에서 트랜잭션 구현 - Stored Procedure
호날두(918225번)에서 메시(291036번)로 송금하려면:
2. ACID 특성 - 트랜잭션의 4가지 핵심 속성
• 데이터베이스의 모든 트랜잭션은 원자성을 보장합니다
• 수행이 되거나 안되거나 - 애매한 상태는 존재하지 않습니다
• "다 되거나! 다 안되거나!"
• 트랜잭션이 완료되면 데이터의 일관성이 보장됩니다
• 무결성 제약을 깨뜨리는 트랜잭션은 실행되지 않습니다
• 예: 존재하지 않는 게시글에 댓글을 달 수 없음
• 트랜잭션이 수행되면 다른 트랜잭션으로부터 영향을 받지 않습니다
• 호날두→메시 송금이 완료되기 전까지 다른 트랜잭션은 변경된 잔액을 볼 수 없습니다
• 트랜잭션이 성공적으로 수행되면 이 결과는 영원히 데이터베이스에 반영됩니다
3. 격리성(Isolation) 레벨 상세 분석
격리성은 성능과 일관성 간의 트레이드오프를 만듭니다. 쇼핑몰에서 마지막 1개 남은 상품을 두 고객이 동시에 구매하려는 상황으로 예시를 들어보겠습니다.
격리 수준별 동작 방식
특징: 하나의 트랜잭션이 완료될 때까지 다른 트랜잭션은 해당 상품의 재고에 접근할 수 없음
장점: 완벽한 일관성 보장
단점: 성능 저하, 대기 시간 발생
특징: 한 트랜잭션 내에서 같은 데이터를 반복해서 읽어도 동일한 결과 보장
동작: 두 고객이 동시에 재고 확인 가능하지만, 실제 재고 감소는 한 명만 성공
결과: 먼저 결제한 고객 성공, 늦은 고객은 실패하거나 대기
특징: 커밋 완료된 데이터만 읽을 수 있음
문제점: Non-Repeatable Read 발생 가능
1. 고객 A가 재고 확인: 1개
2. 고객 B가 구매 완료 (재고 0개로 변경)
3. 고객 A가 재고 재확인: 0개 (이전과 다른 결과!)
특징: 커밋되지 않은 데이터도 읽을 수 있음
문제점: Dirty Read 발생
1. 고객 A가 3개 구매 시작 (재고 5→2개로 변경, 아직 미커밋)
2. 고객 B가 재고 확인: 2개로 보임
3. 고객 A 결제 실패로 롤백 (재고 다시 5개)
4. 고객 B는 잘못된 정보로 구매 결정
격리 수준 선택 가이드라인
• 데이터 일관성이 매우 중요하다면: Serializable 또는 Repeatable Read
• 성능이 더 중요하고 약간의 일관성 저하를 허용: Read Committed
• 성능이 절대적으로 중요: Read Uncommitted (실제 운영환경에서는 거의 사용 안함)
4. 데이터베이스 보안 - 접근 제어
데이터베이스는 서비스의 심장과도 같은 곳입니다. 고객의 개인정보를 포함한 민감한 정보들이 저장되므로 철저한 보안이 필요합니다.
접근 제어의 두 가지 핵심
localhost에서 접근할 수 있는 'messi' 사용자를 생성하고 'goat' 비밀번호로 인증
messi 사용자에게 soccer 데이터베이스에서 SELECT, INSERT, DELETE 권한만 부여
사용자마다 해당 사용자가 컨트롤할 영역에 대해서만 명확하게 권한을 부여해야 합니다. 모든 권한을 부여하면 시스템에 위협이 될 수 있습니다.
5. 데이터 암호화
특히 비밀번호와 같은 민감한 정보는 반드시 암호화되어 저장되어야 합니다.
암호화의 기본 개념
• 복호화: 암호문을 다시 평문으로 복원하는 과정
• 대칭키: 암호화와 복호화에 같은 키 사용
• 비대칭키: 암호화와 복호화에 서로 다른 키 사용
비밀번호 암호화 과정
1. A 사용자가 비밀번호 'sparta' 입력
2. 시스템이 'sparta'를 '3ab0198'로 암호화
3. 데이터베이스에 '3ab0198' 저장
1. A 사용자가 비밀번호 'sparta' 입력
2. 시스템이 'sparta'를 '3ab0198'로 암호화
3. DB에 저장된 '3ab0198'과 비교
4. 일치하면 인증 성공!
비밀번호는 복호화가 불가능한 단방향 암호화를 사용합니다. 암호화 키가 노출되어도 원본 데이터는 보호받을 수 있습니다.
6. SQL Injection 방어
프로그램에서 쿼리 인자를 입력할 때는 반드시 Prepared Statement를 사용하세요!
SQL Injection 공격 예시
다음과 같은 로그인 쿼리가 있다고 가정해봅시다:
악의적인 공격자가 username에 "admin'; --"를 입력하면:
"--"는 SQL 주석이므로 비밀번호 검사 부분이 무시되어 관리자 계정에 무단 접근이 가능해집니다!
Prepared Statement로 방어하기
사용자 입력이 SQL 코드로 해석되는 것을 방지하여 SQL Injection 공격을 완전히 차단할 수 있습니다.
마무리
데이터베이스 트랜잭션과 보안은 모든 개발자가 반드시 알아야 할 핵심 개념입니다. 특히:
1. ACID 특성을 이해하고 적절한 격리 수준 선택
2. 최소 권한 원칙으로 접근 제어 설정
3. 단방향 암호화로 민감한 데이터 보호
4. Prepared Statement로 SQL Injection 방어
이러한 보안 원칙들을 지켜서 안전하고 신뢰할 수 있는 시스템을 구축하시기 바랍니다!
'Daily Logs > TIL (Today I Learned)' 카테고리의 다른 글
DB part.6 (4) | 2025.06.12 |
---|---|
DB part.5 (2) | 2025.06.11 |
DB part.3 (0) | 2025.06.09 |
DB part.2 (0) | 2025.06.08 |
DB part.1 (4) | 2025.06.07 |