파이썬으로 살펴보는 아키텍처 패턴 - 6장

이동욱

2021/11/24

작업 단위 패턴


작업 단위 패턴의 장점


class FakeUnitOfWork(unit_of_work.AbstractUnitOfWork):
    def __init__(self):
        self.batches = FakeRepository([])
        self.commited = False

    def commit(self):
        self.commited = True

    def rollback(self):
        pass


def test_add_batch():
    uow = FakeUnitOfWork()
    services.add_batch("b1", "CRUNCHY-ARMCHAIR", 100, None, uow)
    assert uow.batches.get("b1") is not None
    assert uow.commited


def test_allocate_returns_allocation():
    uow = FakeUnitOfWork()
    services.add_batch("batch1", "CRUNCHY-ARMCHAIR", 100, None, uow)
    result = services.allocate("o1", "COMPLICATED-LAMP", 10, uow)
    assert result == "batch1"
def test_rolls_back_uncommited_work_by_default(session_factory):
    uow = unit_of_work.SqlAlchemyUnitOfWork(session_factory)
    with uow:
        insert_batch(uow.session, 'batch1', 'MEDIUM-PLINTH', 100, None)

    new_session = session_factory()
    rows = list(new_session.execute('SELECT * FROM "batches"'))
    assert rows == []

def test_rolls_back_on_error(session_factory):
    class MyException(Exception):
        pass

    uow = unit_of_work.SqlAlchemyUnitOfWork(session_factory)
    with pytest.raises(MyException):
        with uow:
            insert_batch(uow.session, 'batch1', 'LARGE-FORK', 100, None)
            raise MyException()
        new_session = session_factory()
        rows = list(new_session.execute("SELECT * FROM 'batches'"))
        assert rows == []

명시적 커밋과 암시적 커밋


class AbstractUnitOfWork(abc.ABC):
    def __enter__(self):
        return self

    def __exit__(self, exn_type, exn_value, traceback):
        if exn_type is None:
            self.commit()
        else:
            self.rollback()

정리


작업 단위 패턴은 데이터 무결성 중심의 추상화이다

작업 단위 패턴은 저장소와 서비스 계층 패턴과 밀접하게 연관되어 작동한다

콘텍스트 관리자를 사용하는 멋진 유스케이스이다

SQLAlchemy는 이미 작업 단위 패턴을 제공한다

참고 문헌


>> Home