5월 26일 수요일 (12일차)-DML과 트랜잭션ㅇ

<목차>
ㅇ DML
ㅇ DML에서 트랜잭션
ㅇ DB의 읽기 일관성, 병행제어
ㅇ SYSDATE 함수
ㅇ DUAL 테이블




(8장) 데이터 조작 언어

ㅇ DML (Data Manipulation Language)

  • 테이블에 새 행 추가, 기존 행 수정, 기존 행 삭제
  • DML은 트랜잭션에 영향을 직접적으로 줌
    (셀렉트 명령문은 트랜잭션에 영향을 주는 건 아니었어)
  • DML 명령문은 여러 개 묶어서 묶음을 트랜잭션으로 반영
    (DDL, DCL은 문장 하나가 한 개의 트랜잭션이야)

ㅇ DDL, DCL은 신중하게 실행하기

  • DDL, DCL은 실행과 동시에 AUTO COMMIT이라는 현상이 발생해서 바로바로 저장
  • 예) 회사 DB 날린 놈 이야기 : DDL 명령어에 DROP 수행. 바로 커밋돼서 테이블 삭제돼



ㅇ DB에서의 트랜잭션

  • SELECT는 셀렉트는 트랜잭션에 영향 안 줘
  • DML은 연속적 문장 전체를 하나의 트랜잭션으로 관여
  • DDL, DCL은 문장 1개가 하나의 트랜잭션
  • DML, DDL, DCL은 다 다른 트랜잭션을 생성

CF. TCL (트랜잭션 제어어 Transaction Control Language) ⊂ DCL
: commit, rollback, savepoint

ㅇ DML에서 트랜잭션

  • 수동종료 - 커밋, 롤백이라는 명령문을 직접 쓰는 것
  • 자동종료 - 새로운 트랜잭션이 시작되거나, 프로그램들이 정상종료 하게 될 때 자동으로 오토커밋(AUTO COMMIT)현상 발생
  • 롤백의 예) 실습상황
    • 원래 10번~270번 부서
    • 우리가 INSERT를 이용해서 300~340번까지 삽입했어
    • 아직 저장은 안 한 거야!!!★
      현재는 트랜잭션이 진행 중이라는 거야
    • 롤백하면 ? 다시 270번까지만 나와
  • 새로운 트랜잭션 시작의 예)
  • 정상종료는 sql+프로그램을 정상적으로 빠져나갈 때
    : x버튼 누르거나 exit 명령어 적어서 빠져나가는 것
    • 누가 전원 뽑아버렸다던가, ALT+f4는 비정상 종료라서 오토롤백이 발생

ㅇ SAVEPOINT

  • 그러면 쓰다가 오타나 오류나면 처음으로 돌아가는 건가요?
    : 옛날에는 그랬어.ㅜㅜ 오타, 문법오류, 무결성 등의 에러 상황에 의해 전체 취소...
  • 취소 시점을 구분시켜서 INSERT 명령문마다 SAVEPOINT 줘
  • 그래서 마지막 문장만 롤백하는 방식으로 트랜잭션 보호

ㅇ 문제 : 트랜젝션 몇 개일까?

  • 인서트
    업데이트
    크리에이트
    인서트
    크리에이트
    답 : 4개, 인업/크/인/크

ㅇ 문제 : 1,2,3번 중에 DB에 저장된 것은?

  • 1인서트
    2업데이트
    크리에이트
    롤백
    3인서트
    답 : 1,2번

ㅇ 문제 : 1,2,3,4번 중에 DB에 저장된 것은?

  • 1인서트
    2업데이트
    크리에이트
    3인서트
    롤백
    4인서트
    커밋
    답 : 1,2,4



ㅇ 데이터베이스의 특징 중 하나는 동시성

  • 하나의 데이터베이스에 동시에 여러 명의 유저가 접근해서 작업할 수 있는 환경 제공
  • 수많은 응용프로그램 통해서 하나의 데이터베이스에 접근. 동시에 트랜잭션

ㅇ 데이터베이스의 '읽기 일관성'

  • 1번창 / 2번창 모두 띄워서 동시접속
  • 1번창에서 141번의 급여를 수정 (업데이트, 즉 DML사용) => t1진행 중. 아직 DB에 저장 안 됐어
  • 2번 창에서 141번의 급여를 봤더니 변경되기 이전의 값 보여줘. => 이게 '읽기 일관성'
  • 예)
    현재 : 1명 급여 1억 / 50명 10만원
    120번이 (롤백하면 되니까) 자기 급여 2억으로 업데이트해버림
    t1 수행돼서 : 1명 1억 / 1명 2억 / 49명 10만
    금요일 : 급여 천만 원 인상됐어
    다른 곳에서 t2 수행돼서 : 샐러리가 10만원인 사람들 천만 원으로 업데이트
    지금 상황에서 t2가 t1의 변경된 값을 봐버리면 49명을 찾게 돼
    이걸 커밋하면 1명 1억 / 1명 2억 / 49명은 1000만
    120번 분은 쌤 오는 거 보곤 t1롤백 수행하겠지
    그러면 1명은 1억 / 49명은 1000만 / 혼자만 10만원.....ㅋㅋㅋ (t1만 롤백 돼)
  • 예)
    나무 의자 만들면서 못 하나만 박으면 의자 완성
    화장실 급해서 작업실 문 열어놓고 나갔더니 누군가가 망치로 의자를 뽀개버려
    다른 트랜잭션이 끼어들어 버려
    화장실 갔을 때 문을 잠그고 나갔다면 뽀개지는 못 했겠지 => 락 LOCK
  • t1이 10을 20으로 변경하는 중에 t2가 20을 이용해서 작업을 수행하게 된다면
    이때 t1이 커밋되먼 괜찮은데 롤백해 버리면 20으로 작업했던 t2 의미 없어지잖아
  • 어느 누구도 변경된 값을 보지 않고 일관성 있게 변경되지 않은 값을 보여준다 = 읽기 일관성

ㅇ 병행제어

  • 1창에서 141번 행에 트랜잭션 수행 중인 것을 2창에서 업데이트하려고 해보면
    그냥 커서가 깜빡깜빡 - 데이터베이스 대기상태
  • 병행제어 : 트랜잭션끼리 서로 침범하지 못하도록 관리해줘. LOCK이라는 자원을 활용
  • t1 트랜잭션 수행이 되면 141번 행에 서버가 락을 걸어버려
  • 그래서 2번에서 141번에 뭘 수행하려고 하면 대기 중이 되는 거야. t1이 일을 마칠 때까지
  • t1의 트랜잭션 종료되면 2번창에 오른쪽에서 t2 실행 시작돼
  • 프로젝트 만들 때 주의할 점 : 커밋 넣기
    • 자바 코드 안에 DML 연산 넣으면 반드시 커밋 같이 넣어줘야 해
    • 이거 안 넣으면 트랜잭션 진행 중인 상황이 되고
      다른 응용프로그램으로 뭘 하려고 하면 대기상태가 돼버려
    • 코드에다가 롤백 넣는 건 의미 없...
      넣을 때마다 취소가 돼버리는 것 ㅋㅋㅋㅋ
      인서트 시켰는데 회원가입이 안 되는 거야 ㅋㅋㅋ
  • 142번은 넣으면 잘 돼 - 행이 다르니까 (락이 걸려있는 게 아냐)

ㅇ 만약 서로가 침범하는 상황이 된다면?

  • 대기상태로 있다가 1창에 에러가 떠 : 교착상태 데드락
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
  • 옛날에는 둘 다 대기상태에 트랜잭션 종료 명령문을 실행시킬 수가 없었어 ㅠㅜ 아이고 아이고 하다가 셧다운... 그러다 시스템이 강제로 종료
  • 디비 셧다운은 엄청난 피해 ㅠㅜ 업무시간에는 절대로 셧다운 되면 안돼
  • 그래서 지금은 강제로 조정해서 풀어줘. 트랜잭션들을 종료시켜주는 거야

(나) Q. 그러면 어느 지점까지 풀리는 걸까? 세이브포인트? 아니면 트랜잭션?
실험) 1창에서 142업데이트 -> 2창에서 141업데이트 -> 1창에서 141업데이트하니 락
-> 2창에서 142업데이트하니 락 -> 양쪽 모두 락이라서 데드락 -> 이 때 락이 풀리는 건 1창
: 락이 풀리면서 1창의 두번째 수행은 없는 게 되는 듯. 그러면 세이브포인트로 가는 건가봐.
1창의 142업데이트가 세이브포인트니까. 다만 아직 2창은 락 상태




ㅇ SYSDATE 함수

: 현재 날짜 및 시간을 기록

  • 실제 테이블에 저장되어 있는 데이터가 아니라
    특정 이벤트가 발생했을 때 그때마다 값을 추출해서 보여주는 함수
  • ( USERS 라는 함수도 그러해 : 현재 접속해 있는 유저 아이디 조회)
SELECT sysdate
FROM dual
SQL> /
SYSDATE
--------
21/05/26

오늘 날짜가 출력돼 (정확히는 시스템의 현재 날짜)

  • 사용자들의 로그인 정보를 저장하고 싶을 때 사용
    로그인정보와 날짜를 기록할 수 있어
  • 단점은 연,월,일 밖에 없어. 시간은 다른 방법 (내일 배울 거야)
  • 날짜데이터라서 숫자, 문자인 컬럼에 넣으면 에러나



ㅇ DUAL 테이블

  • 실제 데이터를 가지고 있는 게 아니라 그때그때 마다 값을 추출해서 받아들일 수 있도록 만든 임시 테이블
  • 듀얼 테이블 사용하면 계산도 가능
  • 현업에서 은근 자주 사용해 : 테이블에 저장되어 있지 않은 값을 작업하고 싶을 때
DESC dual
 Name        Null?    Type
 --------- -------- -----------------
 DUMMY                VARCHAR2(1)
 (더미라는 컬럼에 가변길이문자데이터1byte)

SELECT *
FROM dual
DU
----
X
(X라는 값을 가지고 있어. 사실 변수 이름)

좋은 웹페이지 즐겨찾기