AD JB Toolbox 01

MariaDB 강좌 / 두 연결로 격리 수준·잠금·교착 상태 확인하기

격리 수준은 동시에 실행되는 트랜잭션이 어떤 변경을 읽는지 정하고, 잠금은 충돌하는 쓰기 작업의 진행을 조정합니다. 두 개의 별도 연결에서 순서를 통제하면 반복 읽기·읽기 확정, 잠금 대기와 교착 상태의 차이를 실제로 확인할 수 있습니다.

서로 다른 연결 A와 B 준비하기

같은 학습용 서버·shopcourse에 접속한 명령줄 창 두 개를 엽니다. 각 창에서 CONNECTION_ID()가 다른지 확인하고 아래 설정 보관을 각각 실행합니다. 한 창에 A·B 코드를 모두 붙여 넣으면 동시 연결 실습이 되지 않습니다. 운영 서버에서는 이 잠금 실험을 하지 않습니다. 확정·취소의 기본 단위는 트랜잭션 시작하기: InnoDB·COMMIT·ROLLBACK에서 먼저 확인하고, 실습으로 바꾼 SESSION 값은 서버 설정·SQL 모드·시간대·로그 확인하기의 적용 범위와 구분해 복원합니다.

SELECT CONNECTION_ID(),DATABASE(),@@SESSION.tx_isolation;
SET @saved_isolation=@@SESSION.tx_isolation;
SET @saved_wait=@@SESSION.innodb_lock_wait_timeout;

A에서만 아래 테이블을 만듭니다. 이미 있는 이름이면 정의와 데이터를 확인하고 보관할 자료가 없는 이 실습 객체인지 먼저 판단합니다.

USE shopcourse;
CREATE TABLE accounts_36_lab (
 account_id INT PRIMARY KEY,balance INT NOT NULL
) ENGINE=InnoDB;
INSERT INTO accounts_36_lab VALUES(1,1000),(2,2000);
구분 읽기 기준 주의
일반 SELECT의 REPEATABLE READ 트랜잭션 안의 일관된 읽기 스냅샷 FOR UPDATE 같은 현재 읽기와 구분
일반 SELECT의 READ COMMITTED 문장마다 확정된 버전 두 조회 사이 결과 변경 가능
잠금 대기 다른 트랜잭션의 잠금 해제 대기 시간 초과와 교착 상태는 다름

REPEATABLE READ를 A → B → A 순서로 비교하기

앞 절의 초기 상태인 1번 계정 잔액 1000에서 시작합니다. 아래 네 블록의 연결과 순서를 지키고 A가 읽은 뒤에만 B를 실행하세요.

A-1: 스냅샷 형성

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT balance FROM accounts_36_lab WHERE account_id=1;

B-1: 변경 확정

START TRANSACTION;
UPDATE accounts_36_lab SET balance=1100 WHERE account_id=1;
COMMIT;

A-2: 같은 트랜잭션에서 다시 읽기

SELECT balance FROM accounts_36_lab WHERE account_id=1;

A-1과 A-2는 모두 1000입니다. 일반 SELECT의 일관된 읽기 스냅샷을 비교한 것이며 FOR UPDATE 같은 현재 읽기까지 같은 과거 값을 보장한다는 뜻은 아닙니다.

A-3: 종료 후 새 조회

ROLLBACK;
SELECT balance FROM accounts_36_lab WHERE account_id=1;

마지막 조회는 1100입니다. 격리 수준의 적용 범위는 SET TRANSACTION 문서에서 확인할 수 있습니다.

READ COMMITTED도 초기화부터 순서대로 비교하기

B-0: 앞 실습 값 초기화

ROLLBACK;
START TRANSACTION;
UPDATE accounts_36_lab SET balance=1000 WHERE account_id=1;
COMMIT;

A-1: READ COMMITTED의 첫 읽기

ROLLBACK;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT balance FROM accounts_36_lab WHERE account_id=1;

B-1: 1100으로 확정

START TRANSACTION;
UPDATE accounts_36_lab SET balance=1100 WHERE account_id=1;
COMMIT;

A-2: 두 번째 읽기와 종료

SELECT balance FROM accounts_36_lab WHERE account_id=1;
ROLLBACK;

A의 첫 결과는 1000, 두 번째 결과는 1100입니다. 각 일반 읽기가 그 문장 시작 시점에 확정된 버전을 읽기 때문입니다. 실제 격리 수준 선택은 쓰기 충돌·업무 일관성 요구까지 함께 판단합니다.

행 잠금과 대기 시간 초과를 분리해서 확인하기

A-1: 행 1 잠금 유지

START TRANSACTION;
SELECT account_id,balance FROM accounts_36_lab
WHERE account_id=1 FOR UPDATE;

B-1: 같은 행 UPDATE 시도

SET SESSION innodb_lock_wait_timeout=3;
START TRANSACTION;
UPDATE accounts_36_lab SET balance=balance+1 WHERE account_id=1;

A를 종료하지 않으면 B에서 약 3초 후 잠금 대기 시간 초과가 예상됩니다. 이 오류가 트랜잭션 전체를 자동 취소했다고 가정하지 말고 B와 A를 각각 끝냅니다.

B-2: 실패한 작업 정리

ROLLBACK;
SET SESSION innodb_lock_wait_timeout=@saved_wait;

A-2: 잠금 해제

ROLLBACK;

FOR UPDATE의 트랜잭션 적용 조건

교착 상태를 네 번의 교차 실행으로 만들기

두 연결에 열린 트랜잭션이 없는지 확인합니다. 아래는 한 파일로 연속 실행하는 SQL이 아닙니다. A-1 → B-1 → A-2 → B-2 순서로 창을 바꾸며 실행합니다.

순서 연결 동작
1 A row 1 UPDATE
2 B row 2 UPDATE
3 A row 2 UPDATE → wait
4 B row 1 UPDATE → deadlock detection

A-1: 첫 행만 잠그기

START TRANSACTION;
UPDATE accounts_36_lab SET balance=balance+1 WHERE account_id=1;

B-1: 다른 행만 잠그기

START TRANSACTION;
UPDATE accounts_36_lab SET balance=balance+1 WHERE account_id=2;

A-2: B가 보유한 행 요청

UPDATE accounts_36_lab SET balance=balance+1 WHERE account_id=2;

A는 대기하므로 A의 결과를 기다리지 말고 B 창으로 옮겨 다음 문장을 실행합니다.

B-2: A가 보유한 행 요청

UPDATE accounts_36_lab SET balance=balance+1 WHERE account_id=1;

InnoDB가 교착을 탐지하면 한 트랜잭션에서 Deadlock found 오류가 발생할 수 있습니다. 희생 연결은 고정하지 않습니다. 두 창에서 각각 ROLLBACK;을 실행해 남은 변경을 취소합니다. 프로그램은 전체 트랜잭션의 재시도·중복 방지·횟수 제한을 설계해야 합니다.

설정 복원과 동일한 잠금 순서로 개선하기

교착을 줄이려면 여러 행을 항상 같은 키 순서로 접근하고 트랜잭션을 짧게 유지합니다. 인덱스가 없거나 넓은 조건이면 잠금 범위가 커질 수 있습니다. 데드락은 단순 연결 오류와 구분해 실제 로그·쿼리·트랜잭션 순서를 조사합니다. 이 실습은 스케줄을 통제한 작은 기본키 예제입니다.

ROLLBACK;
SET SESSION tx_isolation=@saved_isolation;
SET SESSION innodb_lock_wait_timeout=@saved_wait;
SELECT @@SESSION.tx_isolation,@@SESSION.innodb_lock_wait_timeout;

설정 보관과 복원은 각 창에서 각각 수행합니다. 연결을 끊었다면 사용자 변수는 사라지므로 새 연결의 현재 설정을 다시 조회합니다. 두 창의 트랜잭션을 모두 끝내고 보관할 데이터가 없는 이 실습용 테이블만 정리합니다.

DROP TABLE shopcourse.accounts_36_lab;
같은 카테고리의 다른 글
MariaDB 강좌 / Windows에 MariaDB 설치하고 서버 실행하기

MariaDB 강좌 / Windows에 MariaDB 설치하고 서버 실행하기

Windows MSI 설치에서 서버·클라이언트, 관리자 인증, 서비스와 포트를 설정합니다. SQL 실행을 확인하고 이후 강좌에서 사용할 학습용 계정을 준비하며 시작·접속 오류를 점검합니다.

MariaDB 강좌 / 명령줄 클라이언트로 접속하고 SQL 파일 실행하기

MariaDB 강좌 / 명령줄 클라이언트로 접속하고 SQL 파일 실행하기

터미널 명령과 SQL 입력 위치를 구분하고 학습 계정으로 접속합니다. UTF-8 SQL 파일의 SOURCE 실행, 예상 결과, 오류 중단·한글 표시·경로 문제를 함께 확인합니다.

MariaDB 강좌 / 재귀 CTE로 계층 데이터 조회하고 순환 막기

MariaDB 강좌 / 재귀 CTE로 계층 데이터 조회하고 순환 막기

부모·자식 분류 데이터로 재귀 CTE의 앵커, 재귀 단계, 깊이와 경로를 실습합니다. 종료 조건 변경과 순환 데이터 테스트를 통해 잘린 결과와 무한 반복 위험을 구분합니다.

MariaDB 강좌 / 조회 조건·정렬·페이지 나누기를 개선하기

MariaDB 강좌 / 조회 조건·정렬·페이지 나누기를 개선하기

날짜 범위·정렬·키셋 페이지 조회를 같은 주문 데이터로 검증합니다. 함수 조건의 버전별 최적화, 동점 비교 방향, 포함 검색의 의미와 실제 계획·측정 기준을 설명합니다.

MariaDB 강좌 / WHERE로 조건 지정하기: 비교·AND·OR·IN·BETWEEN·LIKE

MariaDB 강좌 / WHERE로 조건 지정하기: 비교·AND·OR·IN·BETWEEN·LIKE

상품 가격·분류·재고·이름으로 WHERE 조건을 실습합니다. AND·OR 괄호 차이, IN 목록, BETWEEN 경계, LIKE 와일드카드와 실제 퍼센트 검색을 예상 행 번호로 확인합니다.

MariaDB / Query / LEFT JOIN, RIGHT JOIN, INNER JOIN

MariaDB / Query / LEFT JOIN, RIGHT JOIN, INNER JOIN

SQL의 JOIN은 여러 테이블을 한 번에 나타낼 때 사용합니다. 대표적인 JOIN 방식은 LEFT JOIN, RIGHT JOIN, INNER JOIN이 있습니다. 다음은 세 가지 JOIN의 차이를 알아보기 위한 간단한 예제 테이블입니다.

MariaDB / 데이터베이스 저장 위치 변경하는 방법

MariaDB / 데이터베이스 저장 위치 변경하는 방법

MariaDB의 버전이 12.1이라고 할 때, 윈도우용 MariaDB의 기본 설치 위치는 C:\Program Files\MariaDB 12.1, 데이터베이스 저장 위치는 C:\Program Files\MariaDB 12.1\data입니다. 데이터베이스 저장 위치를 다음으로 변경해보겠습니다. D:\Database\MariaDB\data

MariaDB 강좌 / 첫 실습: 상품 테이블을 만들고 데이터를 넣어 조회하기

MariaDB 강좌 / 첫 실습: 상품 테이블을 만들고 데이터를 넣어 조회하기

상품 세 건을 저장하는 전체 SQL로 테이블 생성·입력·조회 과정을 실습합니다. 구조와 행 수, 가격·재고 조건의 예상 결과를 확인하고 반복 입력 오류와 실습 테이블 초기화 범위를 구분합니다.

MariaDB / 피벗 테이블 만드는 방법

MariaDB / 피벗 테이블 만드는 방법

피벗 테이블은 엑셀의 유용한 기능 중의 하나입니다. 예를 들어 아래의 왼쪽 데이터를 오른쪽 표처럼 만드는 것이 피벗 테이블입니다. 조건에 따라 그룹화시켜서 보기 좋게 데이터를 정리하는 것이라 보면 됩니다. MariaDB에서도 몇 가지 함수를 이용하여 피벗 테이블을 만들 수 있습니다.

MariaDB 강좌 / 로컬·원격 접속과 연결 오류 해결하기

MariaDB 강좌 / 로컬·원격 접속과 연결 오류 해결하기

로컬 TCP 연결을 명시하고 서버 정보·현재 계정·실제 테이블 권한을 확인합니다. 연결 거절·인증·DB 오류를 나누어 진단하고 원격 수신 주소·계정·TLS의 적용 조건을 설명합니다.