트랜잭션(Transaction)

잼광·2024년 9월 11일

트랜잭션이란

특정한 작업을 전부 처리하거나, 전부 실패하게 만들어 데이터의 일관성을 보장해주는 기능

예시) 은행 계좌이체
1) A고객의 계좌에서 1000원 차감
2) B고객의 계좌에 1000원 추가
1번 작업이후 2번 작업을 수행하던 중 에러가 발생하게 될 경우 A고객의 계좌에서 1000원이 차감되기만 하는 문제점 발생

위와같이 데이터의 일관성을 유지해야하는 다양한 상황에서 사용

ACID

Atomicity 원자성

  • 트랜잭션에서 실행되는 쿼리마다 하나의 작업단위로 보지않고, 여러개의 작업들을 묶어 하나의 작업단위로 봄

Consistency 일관성

  • 데이터의 일관성을 유지해야하는 특징, 작업이 실패하더라도 작업을 진행하던 도중 실패한 상태로 데이터를 방치하지 않음 (ROLLBACK이 실행되어 트랜잭션 시작 전 상태로 복구)

Isolation 격리성

  • 트랜잭션이 실행 중인 경우 다른 트랜잭션에 의해 데이터가 변경되는 것을 방지
    완전히 수행되거나 수행되지 않은 상태를 외부에서 참조할 수는 있지만, 중간 과정이나 결과를 볼 수 없다.
    *동시성(Concurrency), 격리수준(Isolation Level)

Durability 지속성

트랜잭션이 성공적으로 커밋된 후 해당 데이터가 어떠한 상황에서도 보존되는 특징

*Concurrency Issue

동시에 여러 트랜잭션이 동일안 데이터에 접근할 때 데이터의 일관성을 유지하기 어려움
이런 문제를 해결하기위해, 하나의 클라이언트만 해당 자원을 점유, 다른 사용자가 접근할 수 없도록 하여 자원을 공유하는 원인을 제거 -> Resource Locking

다양한 Lock

  • Shared Locks|READ Locks - SHARE MODE
  • Exclusive Locks|WRITE Locks - FOR UPDATE

Locking Level

  • Global Locks|Database Locks
  • Table Locks
  • Named Locks
  • Metadata Locks

Dead Lock 교착 상태

서로 다른 트랜잭션이 서로의 리소스를 점유하고 있을 때, 서로의 작업이 끝날 때 까지 무한정 기다리게 되는 상태

*트랜잭션의 격리 수준

  1. READ UNCOMMITTED
    • 커밋 되지 않은 읽기를 허용하는 격리 수준
    • 락을 걸지 않아 일관성이 쉽게 깨질 수 있음
  2. READ COMMITTED
    • 커밋 된 읽기만을 허용, SELECT문을 실행할 때 공유락
    • 다른 트랙잭션이 데이터를 수정하고 있는 중에는 데이터를 읽을 수 없음
  3. REPEATABLE READ
    • 읽기를 마치더라도 공유락을 풀지 않으며, 트랜잭션이 완전히 종료될 떄 까지 락을 유지
    • 공유락이 걸린 상태에서 데이터 수정 불가, 데이터 삽입 가능 (팬텀 읽기 발생할 수 있음)
  4. SERIALIZABLE
    • 데이터를 읽는 동안 다른 트랜잭션이 해당 데이터를 읽거나 삽입, 새로운 데이터를 추가하는 것 불가능

프로그래머스 Lv. 1 대충 만든 자판

휴대폰의 자판은 컴퓨터 키보드 자판과는 다르게 하나의 키에 여러 개의 문자가 할당될 수 있습니다. 키 하나에 여러 문자가 할당된 경우, 동일한 키를 연속해서 빠르게 누르면 할당된 순서대로 문자가 바뀝니다.

예를 들어, 1번 키에 "A", "B", "C" 순서대로 문자가 할당되어 있다면 1번 키를 한 번 누르면 "A", 두 번 누르면 "B", 세 번 누르면 "C"가 되는 식입니다.

같은 규칙을 적용해 아무렇게나 만든 휴대폰 자판이 있습니다. 이 휴대폰 자판은 키의 개수가 1개부터 최대 100개까지 있을 수 있으며, 특정 키를 눌렀을 때 입력되는 문자들도 무작위로 배열되어 있습니다. 또, 같은 문자가 자판 전체에 여러 번 할당된 경우도 있고, 키 하나에 같은 문자가 여러 번 할당된 경우도 있습니다. 심지어 아예 할당되지 않은 경우도 있습니다. 따라서 몇몇 문자열은 작성할 수 없을 수도 있습니다.

이 휴대폰 자판을 이용해 특정 문자열을 작성할 때, 키를 최소 몇 번 눌러야 그 문자열을 작성할 수 있는지 알아보고자 합니다.

1번 키부터 차례대로 할당된 문자들이 순서대로 담긴 문자열배열 keymap과 입력하려는 문자열들이 담긴 문자열 배열 targets가 주어질 때, 각 문자열을 작성하기 위해 키를 최소 몇 번씩 눌러야 하는지 순서대로 배열에 담아 return 하는 solution 함수를 완성해 주세요.

단, 목표 문자열을 작성할 수 없을 때는 -1을 저장합니다.

제한사항
1 ≤ keymap의 길이 ≤ 100
1 ≤ keymap의 원소의 길이 ≤ 100
keymap[i]는 i + 1번 키를 눌렀을 때 순서대로 바뀌는 문자를 의미합니다.
예를 들어 keymap[0] = "ABACD" 인 경우 1번 키를 한 번 누르면 A, 두 번 누르면 B, 세 번 누르면 A 가 됩니다.
keymap의 원소의 길이는 서로 다를 수 있습니다.
keymap의 원소는 알파벳 대문자로만 이루어져 있습니다.
1 ≤ targets의 길이 ≤ 100
1 ≤ targets의 원소의 길이 ≤ 100
targets의 원소는 알파벳 대문자로만 이루어져 있습니다

풀이과정
targets 안의 문자열 target 마다 최소 입력 수를 구해야 한다.
문자열을 하나의 알파뱃별로 쪼개기 위해 전개구문을 이용하여 배열에 할당.
각 keymaps 안의 keymap 중 최소한의 입력 횟수를 찾는 함수 구현
알파벳 배열의 요소마다 입력 횟수 메소드 실행하여 최소 횟수 구하기
(도중에 입력할 수 없는 알파벳이 있을 시 -1 반환하고 해당 문자열 반복 중단)
구해진 횟수 정답배열에 push

function solution(keymap, targets) {
    let answer = [];
    for(const target of targets) {
        const charArr = [...target]
        let count = 0;
        for(const char of charArr){
            let cnt = countKey(char, keymap);
            if(cnt !== 0) count += cnt;
            else {count = -1; break;}
        }
        answer.push(count);
    }
    return answer;
}

function countKey(char, keymaps) {
    let find = [];    
    for(const keymap of keymaps) {
        if(keymap.indexOf(char)!== -1) find.push(keymap.indexOf(char));
    }
    if(find.length === 0) return 0;
    else find.sort((a,b)=>a-b);    
    return find[0] + 1;
}

같은 알파벳에 대해서 같은 입력횟수를 가져오게 될텐데 굳이 같은 내용을 반복해 호출하는것 보다 keymap에 존재하는 알파벳들의 최소 입력횟수를 구해두고 각 target 마다 횟수를 구하면 되겠다는 생각이 들었습니다.

0개의 댓글