[DB] 군대로 알아보는 트랜잭션 - 1. 원자성 편

13678 단어 DatabaseDatabase

1. 시나리오

2022년 봄, CC였던 여자친구와 헤어진 Jake는 입대를 결심합니다.
Jake가 살고 있는 나라의 군대 시스템은 절대적입니다. 모든 행정업무의 기준은 시스템이 되고 이에 항의하는 민원은 일절 받아들여지지 않습니다.


2. 트랜잭션의 원자성이 지켜지지 않는다면

원자성의 사전적 정의는 다음과 같습니다.

  • 하나의 원자 트랜잭션은 모두 성공하거나 또는 실패하는 데이터베이스 운용의 집합이다. 원자성의 보증은 데이터베이스의 부분적인 갱신으로 더 큰 문제가 야기되는 것을 방지한다. (출처)

  • 즉, 원자가 더 이상 쪼갤 수 없는 최소한의 단위인 것 처럼 트랜잭션 또한 쪼갤 수 없는 하나의 단위입니다.
    일부만 성공하거나, 일부만 실패하지 않습니다. All or Nothing!

What if... 원자성이 지켜지지 않는다면?

군대 시스템이 다음과 같은 코드로 만들어졌다고 가정하겠습니다.

public class Main {
    public static void main(String[] args) {
        MilitaryInternet militaryInternet = new MilitaryInternet();

        militaryInternet.입대_신청();

        militaryInternet.militaryDB.국가의_부름에_답하라();
    }
}

class MilitaryDB{
    HashSet<String> newSoldiers = new HashSet<>();

    public void 입대(String name) {
        newSoldiers.add(name);
    }

    public void 국가의_부름에_답하라() {
        for (String name : newSoldiers) {
            System.out.println("2022년 3월 23일까지 논산훈련소로 오도록, 훈련병:" + name);
        }
    }
}

class MilitaryInternet{
    Scanner sc = new Scanner(System.in);
    MilitaryDB militaryDB = new MilitaryDB();

    public void 입대_신청() {
        //step 1
        System.out.print("이름을 입력해주세요: ");
        String name = sc.next();

		militaryDB.입대(name);
        
        //step 2
        System.out.print("정말로 입대하시겠습니까? [Y/N]: ");
        String answer = sc.next();

        if(answer.equals("Y")) {
            System.out.println("입대 신청이 완료되었습니다.");
        } else {
            System.out.println("입대 신청이 취소되었습니다.");
        }
    }
}

실연의 슬픔을 이기지 못하고 입대 신청을 하기 위해 컴퓨터를 켠 Jake. 인터넷에 접속해서 입대 신청을 클릭하자 다음과 같은 화면이 나타납니다.

이제 Y 키만 누르면 입대 신청이 끝나는 상황. 그 때, 한통의 전화가 걸려옵니다.
헤어진 전 여자친구입니다! 게다가 당신이 꿈에 그리던 대로, 다시 사귀고 싶다고 합니다. 이런 상황에서 입대할 수는 없습니다.

다행히 입대 신청이 취소되었습니다. 최근 입대 신청을 중간에 취소했음에도 신청이 완료된 것으로 되어 논산 훈련소로 끌려가는 사람들이 있다는 얘기가 소문으로 들려왔지만, 자신과는 상관 없는 헛소문이라고 생각합니다. 하지만...

??!! 어째서 이런 일이!


문제의 원인

문제의 원인은 MilitaryInternet의 코드에 있습니다.

class MilitaryInternet{
    Scanner sc = new Scanner(System.in);
    MilitaryDB militaryDB = new MilitaryDB();

    public void 입대_신청() {
        //step 1
        System.out.print("이름을 입력해주세요: ");
        String name = sc.next();

//		militaryDB.입대(name); //<-- 원자성이 지켜지지 않는 부분.
        
        //step 2
        System.out.print("정말로 입대하시겠습니까? [Y/N]: ");
        String answer = sc.next();

        if(answer.equals("Y")) {
            militaryDB.입대(name);// <--이렇게 변경해야 합니다.
            System.out.println("입대 신청이 완료되었습니다.");
        } else {
            System.out.println("입대 신청이 취소되었습니다.");
        }
    }
}

이렇게 변경하고 나면, 원자성이 지켜져서 더 이상 Jake같이 억울한 청년들이 생겨나지 않겠습니다.


3. 정리

트랜잭션의 원자성: All or Nothing!

좋은 웹페이지 즐겨찾기