home
Unit of work
Architecture patterns with python
에서의 UoW는 이렇게 정의된다.- 작업 단위의 패턴, 즉, 원자적 연산이라는 개념에 대한 추상화이다.
- 작업의 트랜잭션 단위를 정하고, 서비스 계층의 직접적인 데이터 베이스 요청으로 부터 분리시킬 수 있다.
- 책에서 나온 UoW를 조금 변형에서, 레포지토리 클래스를 초기화 때 받아 여러 곳에서 재사용 가능하게 만들었다.
최종본
class AbstractUnitOfWork(metaclass=ABCMeta):
@abstractmethod
def __enter__(self):
pass
@abstractmethod
def __exit__(self):
pass
@abstractmethod
def commit(self):
pass
@abstractmethod
def rollback(self):
pass
class UnitOfWork(AbstractUnitOfWork):
def __init__(self, db: Session, repository_cls):
self._db = db
self._repository_cls = repository_cls
def __enter__(self):
self.repo = self._repository_cls(self._db)
return self
def __exit__(self, *args):
self._db.rollback()
self._db.close()
def commit(self):
try:
self._db.commit()
except SQLAlchemyError:
self.rollback()
raise
def rollback(self):
self._db.rollback()
class UnitOfWorkForRegacy(AbstractUnitOfWork):
def __init__(self, db: Session):
self._db = db
def __enter__(self):
return self
def __exit__(self, *args):
self._db.rollback()
self._db.close()
def commit(self):
try:
self._db.commit()
except SQLAlchemyError:
self.rollback()
raise
def rollback(self):
self._db.rollback()
- 추상 클래스를 만들고, 두 개의 uow가 상속했다.
- uow에 레포지토리를 초기화해 서비스 계층에서는 더 이상 레포지토리에 직접 의존하지 않아도 된다.
- 다만, db를 repository 메서드에 직접 넣는 코드 같은 경우,
db.commit()
만 레포지토리 계층에서 서비스 걔층으로 빼서 하나의 트랜잭션으로 만들어주는 UnitOfWorkForRegacy도 만들어 주었다.