1. Transaction이란
트랜잭션이란 db의 상태를 변경하기 위해 create, update, insert, delete같은 작업의 단위를 말한다.
트랜잭션은 여러개의 상태가 변경되는 작업들을 하나로 실행하는 것 처럼 하나의 unit으로 실행해 성공, 실패의 두가지 상태만을 갖는다.
트랜잭션은 ACID의 4가지 성질이 있다.
1. Atomicity 원자성
트랜잭션의 작업이 중간에 실행되다 멈추지 않는걸 보장해주는 것이다.
2. Consistency 일관성
트랜잭션이 정상적으로 실행되면 db의 상태를 일관성 있게 유지하는것이다. 제약조건이 있다면 그에 위반되는 트랜잭션은 중단되는 것이다.
3. Isolation 독립성
하나의 트랙잭션 작업시 다른 트랜잭션이 중간에 끼어들지 못하는것을 말합니다. 하나의 트랜잭션이 끝나지 않았는데 진행중의 데이터를 다른 트랜잭션이 가져가게 되는 동시성 문제가 생기면 안된다. 그래서 트랜잭션은 연속적으로 동작해야한다.
4. Durability 지속성
완료된 하나의 트랜잭션은 db에 영원히 반영되야 하는 것이다. db에 문제가 생기거나 다른 작업을 해도 남아있어야 한다는 것이다.
2. Transaction 예시
Django로 간단하게 Transaction 상황을 만들어서 예시를 들어본다.
User과 Bank model이 있는 간단한 서비스이다.
간단하게 2명의 유저를 넣고,
신희성과 엄지성에게 balance 3000으로 바꾸려고 하는데 db에는 엄지성이라는 유저가 없다...
저 데이터를 그대로 서버에 보내게 되면
서버는 500에러를 뱉어내지만
db에는 신희성의 잔액이 변경되어있는것을 볼 수 있다.
이런 상황을 방지하기 위해 트랜잭션이 필요하다.
여기서 @transaction.atomic을 추가해주고 똑같이 실행해보면
첫번째 쿼리는 정상적으로 실행되었지만 두번째 쿼리에서 에러가 발생해서 트랜잭션의 상태가 실패가 되어 롤백되었다.
3. Django Transaction
트랜잭션을 쉽게 적용하는 방법은 @transaction.atomic 을 사용하는것이다.
view 함수가 실행되기 전에 트랜잭션이 시작되며 함수의 응답이 문제없이 처리되면 트랜잭션은 db에 커밋되며 종료된다. 트랜잭션 실행중에 예외가 발생시에는 트랜잭션을 롤백한다.
하지만 트랜잭션은 트래픽이 많아질수록 오버헤드가 발생할 수 있다.
view를 반환하면서 Response에서 데이터를 생성하는 경우가 있다. 이때에는 view는 이미 반환되었기 때문에 트랜잭션 외부에서 데이터가 생성된다. 이때 예외가 발생하면 이 예외를 처리할 방법이 없어진다.
1. atomic
원자성을 보장하는 트랜잭션을 래퍼나 with문으로 사용 가능하다.
@transaction.atomic
def view():
do()
def view():
do()
with trasaction.atomic():
to()
on_commit()으로 바로 커밋하는 방법도 있다.
on_commit(success) 이런식으로 다른 함수를 호출할 수 도 있다.
3. TestCase
TestCase는 각 테스트케이스를 트랜잭션으로 래핑하고 테스트 후에 롤백하여 실제 db와 격리한다.
4. LowLevel API
- savepoint()
트랜잭션의 새로운 savepoint를 만듭니다.
- savepoint_commit()
savepoint를 해제한다. savepoint 뒤의 작업들은 모두 트랜잭션의 일부가 된다.
- savepoint_rollback()
savepoint로 롤백한다.
- clean_savepoint()
savepoint를 리셋한다.
@transaction.atomic
def viewfunc(request):
a.save()
sid = transaction.savepoint()
b.save()
if go:
transaction.savepoint_commit(sid)
else:
transaction.savepoint_rollback(sid)
'django' 카테고리의 다른 글
Django - Trailing Slash (1) | 2024.12.02 |
---|---|
Django - DB Connection (0) | 2024.10.27 |
Django core - WSGI (1) | 2024.10.21 |
DRF Serializer (2) | 2024.09.18 |
Django - Nginx + Gunicorn으로 배포하기 (1) | 2024.06.21 |