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 강좌 / 서브쿼리·EXISTS·NOT EXISTS로 조건 표현하기

MariaDB 강좌 / 서브쿼리·EXISTS·NOT EXISTS로 조건 표현하기

평균값 서브쿼리와 EXISTS·NOT EXISTS를 상품·고객·주문으로 실습합니다. 한 값의 반환 조건, 상관 키 누락, paid 주문 부재의 정의와 NOT IN의 NULL 함정을 설명합니다.

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 강좌 / 중복 데이터를 줄이는 정규화와 주문 데이터베이스 설계

주문 상세에 반복한 고객 정보의 변경 오류를 관찰하고 키별 사실을 네 테이블로 나눕니다. 부분·이행 종속, 거래 당시 단가와 스냅샷 보존, 무결성 제약과 성능의 별도 검토를 설명합니다.

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 강좌 / 최종 실습: 주문 데이터베이스 구축부터 권한·백업·복원까지

주문 DB 구축·제한 계정·재고와 주문의 트랜잭션을 한 흐름으로 실습합니다. 확정 상태를 덤프해 별도 DB로 복원하고 행·금액·재고·키·권한 실패 조건으로 완성 여부를 검증합니다.

MariaDB 강좌 / GROUP BY·HAVING으로 묶고 집계 결과 걸러내기

MariaDB 강좌 / GROUP BY·HAVING으로 묶고 집계 결과 걸러내기

GROUP BY로 분류별 상품 수·재고·금액을 계산하고 HAVING으로 그룹을 제한합니다. WHERE 적용 시점과 비집계 열·SQL 모드·NULL 그룹의 주의점을 비교 실습으로 설명합니다.

MariaDB 강좌 / 사용자 계정 만들고 필요한 권한만 부여하기

MariaDB 강좌 / 사용자 계정 만들고 필요한 권한만 부여하기

사용자·호스트 조합을 확인하고 상품 한 테이블의 SELECT만 허용하는 계정을 만듭니다. 새 연결의 허용·거절 시험, 권한 회수와 기존 계정을 덮어쓰지 않는 정리 절차를 설명합니다.

MariaDB 강좌 / 서버 설정·SQL 모드·시간대·로그 확인하기

MariaDB 강좌 / 서버 설정·SQL 모드·시간대·로그 확인하기

설정 파일·GLOBAL·SESSION의 차이를 기준으로 MariaDB 동작을 확인합니다. SQL 모드 오류와 TIMESTAMP·DATETIME 시간대 실습, 로그 조건 점검 및 변경 복구 절차를 제공합니다.

MariaDB 강좌 / ORDER BY·LIMIT로 정렬하고 조회 범위 제한하기

MariaDB 강좌 / ORDER BY·LIMIT로 정렬하고 조회 범위 제한하기

ORDER BY의 여러 열·방향과 LIMIT·OFFSET을 같은 가격의 상품으로 실습합니다. 동점 해소, 페이지 경계 변화, 마지막 정렬값을 이용한 조회와 NULL 배치를 설명합니다.

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

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

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