잡동사니

Isolation Level이 가지는 의미와 각 Level의 특성 with Lock 본문

IT/Database

Isolation Level이 가지는 의미와 각 Level의 특성 with Lock

yeTi 2022. 5. 31. 16:16

안녕하세요. yeTi입니다.

오늘은 Springframwork에서 제공하는 Transactional 의 옵션은 Isolation 의 특성을 MySQL 8.0의 공식 문서 를 통하여 정리하고자 합니다.

개요

모든 Database SystemACID의 원칙을 준수하는 방향으로 만들어지는데요.

ACID는 트랜젝션의 개념과 밀접하게 관련이 있습니다.

하지만 ACID 를 준수하면 높은 수준의 성능을 기대하기 어렵기 때문에, 데이터의 격리 수준을 나눠 성능과 데이터 일관성을 적절하게 조절하여 사용할 수 있도록 지원하고 있습니다.

ACID

Atomicity : 한 프로세스에서 보장되어야하는 데이터의 변경점이 일괄적으로 변경되거나 변경되지 않는 특징입니다.

Consistency : 트랜젝션이 진행되는 동안에는 다른 트랜젝션에 의해 변경되는 데이터가 반영되지 않도록 데이터의 일관성을 유지하는 특징입니다.

Isolation : 트랜젝션간 데이터 격리 수준을 의미합니다. 이는 Locking 에 의해서 구현되는되요. 격리 수준에 따라서 성능이나 동시성에 영향을 줍니다.

Durability : 데이터에 대한 신뢰성으로 commit 된 데이터는 어떠한 장애 상황에서도 보존할 수 있는 특징입니다.

Dirty read

문서에서 설명한 dirty read 는 다음과 같습니다.

An operation that retrieves unreliable data, data that was updated by another transaction but not yet committed. It is only possible with the isolation level known as read uncommitted.
This kind of operation does not adhere to the ACID principle of database design. It is considered very risky, because the data could be rolled back, or updated further before being committed; then, the transaction doing the dirty read would be using data that was never confirmed as accurate.
Its opposite is consistent read, where InnoDB ensures that a transaction does not read information updated by another transaction, even if the other transaction commits in the meantime.

의미를 간략하게 요약하자면,
dirty read 란, 트랜젝션을 커밋하지 않은 데이터를 읽는 행위입니다.

non-repeatable read

문서에서 설명한 non-repeatable read 는 다음과 같습니다.

The situation when a query retrieves data, and a later query within the same transaction retrieves what should be the same data, but the queries return different results (changed by another transaction committing in the meantime).
This kind of operation goes against the ACID principle of database design. Within a transaction, data should be consistent, with predictable and stable relationships.
Among different isolation levels, non-repeatable reads are prevented by the serializable read and repeatable read levels, and allowed by the consistent read, and read uncommitted levels.

의미를 간략하게 요약하자면,
non-repeatable read 란, 동일 트랜젝션내에서 반복적으로 데이터를 조회시 다른 트랜젝션에 의해 변경된 데이터가 조회되는 행위입니다.

Phantom read

문서에서 설명한 phantom 은 다음과 같습니다.

A row that appears in the result set of a query, but not in the result set of an earlier query. For example, if a query is run twice within a transaction, and in the meantime, another transaction commits after inserting a new row or updating a row so that it matches the WHERE clause of the query.
This occurrence is known as a phantom read. It is harder to guard against than a non-repeatable read, because locking all the rows from the first query result set does not prevent the changes that cause the phantom to appear.
Among different isolation levels, phantom reads are prevented by the serializable read level, and allowed by the repeatable read, consistent read, and read uncommitted levels.

의미를 간략하게 요약하자면,
phantom read 란, 동일 트랜젝션내에서 반복적으로 데이터를 조회시 다른 트랜젝션에 의해 추가되거나 변경된 데이터가 조회되는 행위입니다.

Consistent read

문서에서 설명한 consistent read 은 다음과 같습니다.

A read operation that uses snapshot information to present query results based on a point in time, regardless of changes performed by other transactions running at the same time. If queried data has been changed by another transaction, the original data is reconstructed based on the contents of the undo log. This technique avoids some of the locking issues that can reduce concurrency by forcing transactions to wait for other transactions to finish.
With REPEATABLE READ isolation level, the snapshot is based on the time when the first read operation is performed. With READ COMMITTED isolation level, the snapshot is reset to the time of each consistent read operation.
Consistent read is the default mode in which InnoDB processes SELECT statements in READ COMMITTED and REPEATABLE READ isolation levels. Because a consistent read does not set any locks on the tables it accesses, other sessions are free to modify those tables while a consistent read is being performed on the table.

의미를 간략하게 요약하자면,
consistent read 란, 스냅샷 정보를 기준으로 데이터를 조회하는 것입니다. 스냅샷의 생성 시점은 REPEATABLE READ 수준에서는 첫 조회 시점을 기준으로 하고, READ COMMITTED 수준에서는 매 조회 시점마다 생성합니다.
참고적으로 dirty read 와 다른 점은 dirty read 는 커밋되지 않은 데이터들도 읽는 현상이고 consistent read 는 스냅샷 시점의 데이터를 읽는 행위입니다.

READ UNCOMMITTED

문서에서 설명한 READ UNCOMMITTED 은 다음과 같습니다.

The isolation level that provides the least amount of protection between transactions. Queries employ a locking strategy that allows them to proceed in situations where they would normally wait for another transaction. However, this extra performance comes at the cost of less reliable results, including data that has been changed by other transactions and not committed yet (known as dirty read). Use this isolation level with great caution, and be aware that the results might not be consistent or reproducible, depending on what other transactions are doing at the same time. Typically, transactions with this isolation level only do queries, not insert, update, or delete operations.

의미를 간략하게 요약하자면,
READ UNCOMMITTEDdirty read, non-repeatable read, phantom read를 모두 허용함으로써 다른 트랜젝션의 변경전 데이터를 조회하는 특성이 있습니다. 따라서 일반적으로 해당 수준의 격리는 트랜잭션내에 쿼리만 수행하고 삽입, 업데이트 또는 삭제 작업은 수행하지 않습니다.

해당 격리 수준에서는 일반적인 read시에는 snapshotLock 모두를 활용하지 않고, SELECT with FOR UPDATE or FOR SHARE, UPDATE, DELETE 시에만 record lock 을 사용합니다.

READ COMMITTED

문서에서 설명한 READ COMMITTED 은 다음과 같습니다.

An isolation level that uses a locking strategy that relaxes some of the protection between transactions, in the interest of performance. Transactions cannot see uncommitted data from other transactions, but they can see data that is committed by another transaction after the current transaction started. Thus, a transaction never sees any bad data, but the data that it does see may depend to some extent on the timing of other transactions.
When a transaction with this isolation level performs UPDATE ... WHERE or DELETE ... WHERE operations, other transactions might have to wait. The transaction can perform SELECT ... FOR UPDATE, and LOCK IN SHARE MODE operations without making other transactions wait.
SELECT ... FOR SHARE replaces SELECT ... LOCK IN SHARE MODE in MySQL 8.0.1, but LOCK IN SHARE MODE remains available for backward compatibility.

의미를 간략하게 요약하자면,
READ COMMITTEDREAD UNCOMMITTED보다 보완수준을 강화한 격리수준으로 dirty read는 허용하지 않지만 non-repeatable read, phantom read는 허용하는 격리수준입니다. 즉, 자신의 트랜젝션내에서 다른 트랜젝션이 커밋한 데이터를 읽을 수 있도록 해줍니다.

해당 격리 수준에서는 일반적인 read시에는 snapshot 을 활용하기 때문에 Lock 을 사용하지 않고, SELECT with FOR UPDATE or FOR SHARE, UPDATE, DELETE 시에만 record lock 을 사용합니다.

REPEATABLE READ

문서에서 설명한 REPEATABLE READ 은 다음과 같습니다.

The default isolation level for InnoDB. It prevents any rows that are queried from being changed by other transactions, thus blocking non-repeatable reads but not phantom reads. It uses a moderately strict locking strategy so that all queries within a transaction see data from the same snapshot, that is, the data as it was at the time the transaction started.
When a transaction with this isolation level performs UPDATE ... WHERE, DELETE ... WHERE, SELECT ... FOR UPDATE, and LOCK IN SHARE MODE operations, other transactions might have to wait.
SELECT ... FOR SHARE replaces SELECT ... LOCK IN SHARE MODE in MySQL 8.0.1, but LOCK IN SHARE MODE remains available for backward compatibility.

의미를 간략하게 요약하자면,
REPEATABLE READ 는 InnoDB의 기본 격리 수준으로 dirty read, non-repeatable read를 허용하지 않고, phantom read만 허용하는 격리수준입니다. 즉, 자신의 트랜젝션내에서 반복해서 데이터를 조회하더라도 동일한 데이터를 읽도록 보장하지만 새로운 데이터는 나타날 수 있습니다.

해당 격리 수준에서는 일반적인 read시에는 snapshot 을 활용하기 때문에 Lock 을 사용하지 않고, SELECT with FOR UPDATE or FOR SHARE, UPDATE, DELETE 시에만 record lock 이나 gap lock 을 사용합니다.

SERIALIZABLE

문서에서 설명한 REPEATABLE READ 은 다음과 같습니다.

The isolation level that uses the most conservative locking strategy, to prevent any other transactions from inserting or changing data that was read by this transaction, until it is finished. This way, the same query can be run over and over within a transaction, and be certain to retrieve the same set of results each time. Any attempt to change data that was committed by another transaction since the start of the current transaction, cause the current transaction to wait.
This is the default isolation level specified by the SQL standard. In practice, this degree of strictness is rarely needed, so the default isolation level for InnoDB is the next most strict, REPEATABLE READ.

의미를 간략하게 요약하자면,
SERIALIZABLEdirty read, non-repeatable read, phantom read 모두를 허용하지 않는 격리수준입니다.
특정 트랜젝션이 데이터를 읽는 동안 다른 트랜젝션은 데이터를 추가하거나 변경할 수 없습니다. 이 때, 다른 트랜젝션 또한 데이터를 읽은 후 두 트랜젝션이 데이터의 추가나 수정을 시도하면 dead lock 이 발생합니다.

해당 격리 수준에서 lock 정책은 REPEATABLE READ 와 동일하지만, SELECTSELECT ... FOR SHARE 를 사용합니다. (autocommit이 동작하지 않을때)

참고문헌

Comments