Akashic Records

Oracle Transactions and Concurrency 본문

Database Learning Guide

Oracle Transactions and Concurrency

Andrew's Akashic Records 2023. 3. 14. 13:04
728x90

Oracle 데이터베이스에서 트랜잭션은 하나 이상의 SQL 문장으로 구성됩니다. 각각의 SQL 문장은 트랜잭션 단위로 실행됩니다. 즉, 트랜잭션이 성공적으로 완료되기 위해서는 모든 SQL 문장이 성공적으로 실행되어야 합니다. 만약 SQL 문장 중 하나라도 실패한다면, 트랜잭션은 롤백되어 이전 상태로 되돌아가게 됩니다.

 

Oracle 데이터베이스에서는 트랜잭션을 관리하기 위해 여러 가지 컴포넌트를 사용합니다. 그 중에서도 가장 중요한 것은 REDO 로그와 UNDO 로그입니다. 

  • REDO 로그는 데이터베이스의 상태를 변경하는 모든 작업을 로깅하는 기능을 수행합니다. 이를 통해 데이터베이스의 변경 내역을 추적하고, 시스템 장애 시에 데이터를 복구할 수 있습니다. 
  • UNDO 로그는 각각의 트랜잭션에 대한 이전 상태의 정보를 유지하는 로그입니다. 이를 통해 롤백이나 복구 시에 이전 상태로 되돌릴 수 있습니다.

Oracle 데이터베이스에서는 동시성을 관리하기 위해 Locking 기법을 사용합니다. Locking은 여러 사용자가 동시에 데이터를 변경할 때, 각각의 트랜잭션이 데이터를 정확히 읽고 쓸 수 있도록 보장하는 기술입니다. Oracle에서는 여러 종류의 Locking 기법을 지원합니다. 

예를 들어, Shared Locking은 여러 사용자가 동시에 데이터를 읽을 수 있지만, Exclusive Locking은 데이터를 변경하는 사용자가 다른 사용자와 충돌하지 않도록 보장합니다.

 

트랜잭션은 Oracle 데이터베이스에서 중요한 개념입니다. 트랜잭션을 안전하게 처리하기 위해서는 ACID 원칙을 따르는 것이 중요합니다. 또한, REDO 로그와 UNDO 로그를 이용해 데이터베이스의 변경 내역을 추적하고, 롤백이나 복구 시에 이전 상태로 되돌릴 수 있도록 관리해야 합니다. 마지막으로, 동시성을 관리하기 위해 Locking 기법을 사용해야 하며, 이를 통해 여러 사용자가 동시에 데이터를 정확하게 읽고 쓸 수 있도록 보장해야 합니다.

 

Q. ACID 원칙에 대해서 상세하게 설명해줘

ACID 원칙은 데이터베이스 트랜잭션을 안전하게 처리하기 위한 원칙으로, 다음과 같이 네 가지 원칙을 의미합니다.

  • 원자성 (Atomicity) : 트랜잭션은 All or Nothing 원칙을 따릅니다. 즉, 트랜잭션 내의 모든 작업이 완료되어야만 트랜잭션이 완전히 수행된 것으로 인정됩니다. 만약 트랜잭션 수행 중 실패가 발생하면, 트랜잭션 전체가 롤백되어 이전 상태로 되돌아가게 됩니다.
  • 일관성 (Consistency) : 트랜잭션은 데이터베이스의 일관성을 유지해야 합니다. 즉, 트랜잭션 수행 전과 수행 후에 데이터베이스의 일관성이 유지되어야 합니다. 이를 위해 트랜잭션 수행 중 데이터베이스의 일관성을 깨지 않도록 보장해야 합니다.
  • 고립성 (Isolation) : 동시에 여러 개의 트랜잭션이 수행되는 경우, 각각의 트랜잭션은 다른 트랜잭션에 영향을 주지 않도록 고립되어야 합니다. 이를 위해 Locking 기법을 사용해야 합니다.
  • 지속성 (Durability) : 트랜잭션이 성공적으로 완료된 후, 해당 데이터의 변경 내역은 영구적으로 보존되어야 합니다. 이를 위해 REDO 로그와 UNDO 로그를 사용해 데이터의 변경 내역을 추적하고, 데이터베이스 장애 시에도 데이터를 복구할 수 있도록 보장해야 합니다.

ACID 원칙은 데이터베이스 트랜잭션을 안전하게 처리하기 위한 원칙으로, 이를 지키는 것이 중요합니다. 이를 위해서는 데이터베이스의 일관성, 동시성, 변경 내역 추적, 데이터의 영구 보존 등의 요소를 고려해야 합니다.

 

Q. 오라클 데이터 베이스 "동시성 제어"에 대해서 알려줘

오라클 데이터베이스의 "동시성 제어(Concurrency Control)"는 여러 사용자가 동시에 데이터베이스에 접근할 때 발생할 수 있는 충돌을 방지하고, 데이터 일관성을 유지하기 위한 메커니즘입니다.


동시성 제어는 크게 Locking과 Multi-version Concurrency Control (MVCC) 두 가지 방법으로 구현됩니다.

  • Locking: 트랜잭션이 데이터를 사용할 때, 해당 데이터를 잠근 후에 사용하게 되는 방식입니다. Locking은 Exclusive Lock과 Shared Lock 두 가지 종류가 있습니다. Exclusive Lock은 해당 데이터를 사용하는 트랜잭션이 완전히 종료될 때까지 다른 트랜잭션이 해당 데이터를 사용하지 못하도록 합니다. Shared Lock은 여러 트랜잭션이 해당 데이터를 공유하여 사용할 수 있도록 합니다.
  • MVCC: 각각의 트랜잭션이 독립적인 작업 공간(Workspace)을 가지고, 동시에 여러 버전의 데이터를 관리합니다. 이 때, 각 버전의 데이터는 Timestamp나 SCN(System Change Number)과 같은 값을 가지고 있어서, 각각의 트랜잭션이 원하는 데이터 버전을 선택할 수 있습니다. MVCC는 Locking보다는 Overhead가 적으며, Concurrency가 높아질수록 성능이 더욱 향상됩니다.

동시성 제어를 통해 여러 사용자가 동시에 데이터베이스를 사용할 때 충돌이 발생하지 않도록 보장하고, 데이터의 일관성을 유지할 수 있습니다. 이를 위해 오라클 데이터베이스는 Locking과 MVCC 두 가지 방식을 제공하고 있으며, 이 중에서 사용자가 선택할 수 있습니다.

 

락(lock)을 이용한 동시성 제어

오라클 데이터베이스에서는 락(lock)을 이용한 동시성 제어를 구현할 수 있습니다. 락을 이용한 동시성 제어를 구현하려면 SELECT ... FOR UPDATE 구문을 사용하여 특정 레코드에 대한 락을 획득하고, 락이 획득된 후에 해당 레코드를 수정하면 됩니다. 다음은 이를 파이썬과 cx_Oracle 패키지를 이용해 구현한 예시 코드입니다.

import cx_Oracle

# Oracle 데이터베이스 연결 정보
dsn = cx_Oracle.makedsn(host="hostname", port="port", sid="dbname")
connection = cx_Oracle.connect(user="username", password="password", dsn=dsn)

# 커서 생성
cursor = connection.cursor()

# 락 획득을 위한 SQL 실행
cursor.execute("SELECT * FROM table WHERE column = :value FOR UPDATE", {"value": some_value})

# 락이 획득된 후에 해당 레코드를 업데이트하는 SQL 실행
cursor.execute("UPDATE table SET column = :new_value WHERE column = :value", {"new_value": new_value, "value": some_value})

# 커밋
connection.commit()

# 연결 닫기
cursor.close()
connection.close()

위 코드에서 SELECT ... FOR UPDATE 구문은 락을 획득하기 위한 구문입니다. 이 구문은 특정 레코드에 대해 락을 획득하고 다른 트랜잭션이 해당 레코드를 수정하지 못하도록 방지합니다. 그리고 UPDATE 구문은 락이 획득된 후에 실행되어 해당 레코드를 업데이트합니다. 마지막으로 commit()을 호출해 트랜잭션을 커밋하고, 커서와 연결을 닫습니다. 이렇게 하면 락을 이용한 동시성 제어가 가능합니다.

728x90
Comments