본문 바로가기

이론

ORM과 트랜잭션

목차

     

    트랜잭션

    - 데이터베이스에서의 연속적인 작업 단위를 의미

    - ACID 특성을 보장해야함

    • 원자성 (Atomicity): 트랜잭션은 하나의 작업 단위로 처리되며, 모든 작업이 성공하거나 모두 실패해야 한다
    • 일관성 (Consistency): 트랜잭션이 시작되기 전과 종료된 후 데이터베이스는 일관된 상태여야 한다
    일관된 상태
    정의: 데이터베이스가 모든 규칙을 지키며 오류 없이 정확한 데이터를 담고 있다
    ex) - 무결성 제약 조건: PK는 고유한 값이다, 외래키는 반드시 참조되는 테이블의  유효한 값을 가진다 
          - 비즈니스 규칙: 은행 잔고는 음수일 수 없다
    • 격리성 (Isolation): 동시에 여러 트랜잭션이 실행될 때, 각각의 트랜잭션은 다른 트랜잭션의 중간 상태를 볼 수 없다 (트랜잭션 간의 충돌 방지)
    • 지속성 (Durability): 트랜잭션이 성공적으로 완료된 후, 그 결과는 영구적으로 저장되어야 한다 

     

    ORM (Object-Relational Mapping)

    - 객체지향 프로그래밍에서 사용되는 데이터베이스와의 상호작용을 쉽게 해주는 기술

    - ORM은 객체지향 프로그래밍의 객체와 관계형 데이터베이스의 테이블 간의 변환을 자동으로 처리해줌

     

     

    주요 기능

    • 객체와 테이블 간 매핑
    • CRUD 작업 자동화 → SQL을 직접 작성할 필요 X
    • 쿼리 추상화 → SQL 쿼리를 객체 지향적을 표현할 수 있도록 함
    • 데이터베이스 독립성 → 데이터베이스를 변경해도 ORM 코드는 거의 수정 X

     

    장점

    ① 코드 가독성 증가

    ② 생산성 향상 (개발 속도 ↑)

    ③ 유지보수 용이

    ④ 보안 → SQL 인젝션 공격 방어

    SQL 인젝션 공격
    정의: 웹 사용자가 입력한 데이터를 직접 SQL 쿼리에 삽입할 때 발생
    방어: ORM은 쿼리를 매개변수화하여 자동으로 처리한다. 매개변수화된 쿼리는 사용자가 제공하는 데이터를 쿼리의 "값"으로만 처리하여 안전하다.

     

     

    단점

    ① 성능 문제, 자동으로 SQL을 생성하므로 효율적인 쿼리가 생성되지 않을 수 있다

    복잡한 쿼리 처리 어려움

    ③ 추상화로 인한 성능 저하

     

     

    ORM에서 트랜잭션 사용 시 발생 쿼리 매커니즘

    트랜잭션 흐름

    1) 트랜잭션 시작, 세션을 생성하면 트랜잭션 시작

    session.begin()

    ORM이 해당 코드를 분석하여 해당 작업에 필요한 SQL 쿼리 생성

    BEGIN TRANSACTION;

     

    트랜잭션 수동 제어 vs 자동 관리
    수동 제어 
    session.begin()을 직접 호출

    자동 관리
    트랜잭션이 필요한 작업 (ex) INSERT, UPDATE, DELETE)을 수행하면 ORM이 자동으로 session.beigin을 호출하여 트랜잭션을 시작함

     

     

     

    2) 작업 수행, ORM은 내부적으로 SQL 쿼리를 생성하고 데이터베이스에 전송

    INSERT INTO users (name, age) VALUES ("bini", 10);
    UPDATE users SET age = 20 WHERE name ='bini';
    DELETE FROM users where name = 'bini';

     

    3) 커밋(COMMIT), 모든 작업이 성공적으로 완료되면 트랜잭션을 커밋

    session.commit()
    COMMIT;

     

    4) 롤백(ROLLBACK), 중간에 오류가 발생하면 트랜잭션을 취소하고 이전 상태로 되돌림

    session.rollback()
    ROLLBACK;

     

    5) 저장점(SAVEPOINT), 트랜잭션 내에서 부분적으로 저장점을 만들고, 그 시점으로 롤백할 수 있음

    savepoint1 = session.connection().execute("SAVEPOINT sp1");
    
    //
    ...
    //
    // 문제 발생
    if some_condition:
    	session.connection().execute("ROLLBACK TO SAVEPOINT sp1");
        
    // Savepoint 해제
    session.connection().execute("RELEASE SAVEPOINT sp1");
    session.commit();
    Q. Savepoint를 해제하지 않는다면?
    A. 해당 트랜잭션이 종료될 때까지(커밋 또는 롤백) 데이터베이스가 해당 Savepoint에 대한 정보를 유지함
    이 때 롤백으로 인한 해제는 해당 SAVEPOINT보다 이전 시점의 SAVEPOINT로의 롤백을 뜻한다.
    ...
    SAVEPOINT sp1;
    -- 문제 발생
    ROLLBACK TO SAVEPOINT sp1;
    ...
    -- Savepoint 삭제
    RELEASE SAVEPOINT savepoint_name;
    ...
    COMMIT;