프로젝트 할 당시에, get_or_create
함수를 사용하면서 transaction에 대해 잠깐 찍먹(?)을 했었다.
transaction이라 하면,
ACID 관련해서는 지난 글 참고.
Transactions specify an isolation level that defines how one transaction is isolated from other transactions.
(출처: Microsoft - Understanding isolation levels)
Isolation level은 여러 transcation이 진행될 때, 그들끼리 얼마나 고립되어 있는가 = 어느 수준까지 transaction 원칙을 보장하는가를 결정하는 것이다.
ACID 원칙을 엄격하게 지키다보면, concurrency 성능이 떨어지기 때문에 level 별로 side effect 허용 수준을 정한 것.
level 별 발생하는 현상에 대해 먼저 짚고 넘어가자.
아.. 자꾸 phantom read가 phantom thread로 읽혀...
가장 높은 Isolation level로, read/write/range locks가 요구된다. 중간에 새로운 데이터가 insert되는 것도 막는다.
select ... where id between 10 and 20
의 조건으로 한 transaction이 쿼리를 진행할 때, 해당 범위에 exclusive lock이 걸려 다른 transaction이 id=15
에 해당하는 데이터를 insert하지 못하고 대기 상태에 빠짐 그래서 dirty read/non-repeatable read/phantom read의 문제가 발생하지 않으나 dead lock 상태에 놓일 수 있다.
뿐만 아니라, concurrency 기능이 떨어질 수 있다.
level 2 - Repeatable Read
한 transaction 내에서 여러 번 데이터를 읽어도 데이터가 변하지 않음을 보장하는 level.
(read/write lock 사용)
1번 transaction이 읽은 데이터는 해당 transaction이 종료될 때까지 갱신/삭제를 allow하지 않는다.
하지만 다른 transaction에 의해 새로 insert된 데이터가 생겨버리는 phantom read는 막지 못한다.
(range lock 사용x)
level 1 - Read committed
commit 된 데이터만 읽을 수 있도록 허용하는 level.
Dirty read는 방지할 수 있으나, non-repeatable read/phantom read는 막을 수 없다. 그래서 한 transaction 에서 데이터를 여러 번 read할 때, 데이터의 일관성은 보장할 수 없다.
level 0 - Read uncommitted
commit되지 않은 데이터까지 읽을 수 있도록 허용하는 level.
따라서 Dirty read/Non-repeatble read/phantom read를 막을 수 없고, 최종적으로 rollback될 수도 있는 데이터까지 읽을 수 있는 위험이 있다.
우선 Microsoft 문서를 보면, 최소 Repeatable read
는 적용해야 한다고 되어 있다.
Transactions must be run at an isolation level of at least repeatable read to prevent lost updates that can occur when two transactions each retrieve the same row.
Serializable
단계까지 적용하면 언급된 이슈들은 최소화할 수 있겠지만 동시처리 기능이 매우 저하되므로, 그래서 문서들에 설명된 것처럼 Repeatable read
를 필요한 경우에만 Serializable
까지 적용하는 것 같다.
데이터베이스 종류에 따라, lock은 걸지 않아도 특정 시점을 제외한 변경 사항은 모두 무시하여 데이터 일관성을 유지하는 설정 등이 제공되기도 한다고 한다.
참고 자료
https://docs.microsoft.com/en-us/sql/connect/jdbc/understanding-isolation-levels?view=sql-server-ver15
https://en.wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels
https://www.geeksforgeeks.org/transaction-isolation-levels-dbms/
https://www.letmecompile.com/mysql-innodb-lock-deadlock/