bulk_create시 내부적으로 context manager를 통해 트랜잭션을 하나 더 만든다. 이건 내 예상인데, spring처럼 트랜잭션 매니저가 물리 트랜잭션으로 묶는 식으로 동작하는 것이 아니라 진짜 별개로 트랜잭션이 하나 더 뜨는 것으로 보인다. (이것은 가설일 뿐이고 정확힌 공부 혹은 실험을 해봐야 안다) 트랜잭션을 하나 더 만든다고 표현한 것이다.
즉, READ COMMITED 이상이면 다른 트랜잭션이면 조회할 수 없는 것이 당연할 것이다. 그렇다면 우리의 트랜잭션 격리 수준은 무엇일까? InnoDB의 기본 전략이 REPEATABLE READ니까 너무 당연하게 REPEATABLE READ일까? 정답은 아니다.
django에서는 MySQL default인 REPEATABLE READ가 아니라 READ COMMITTED일때 best라고 표현한다. 그래서 default로 이걸로 두었다. 트랜잭션 순서에 따라 문제가 발생할 수도 있는 부분이라... 트랜잭션이 깊어지면 기억은 해두는 게 좋아 보인다
아무튼 이 문제를 어떻게 해결했을까? 간단하다. 컨텍스트 매니저로 트랜잭션 범위를 좁혀주었다
some_view():
with transaction.atomic:
svc1.create()
svc2.bulk_create()
svc3.retrieve()