Skip to content

Commit

Permalink
feat: uow 레거시 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
leehjhjhj committed Jul 1, 2024
1 parent 7b5c3f9 commit 5a88f53
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions python/unit of work로 레거시 극복하기.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# unit of work로 레거시 극복하기
- 기존의 레포지토리 레이어의 로직에는 각 SQL문에 한번씩 `commit()`을 수행했다.
- 이렇게 되면 `session.begin()`이나 `session.begin_nested()`을 수행하더라도 `commit()`이 savepoint를 빠져 나가서 의미가 없어진다.
- 그래서 생각한 것이 commit을 flag의 True False로 관리하면 되지 않을까? 였다.

``` python
class CustomSession(Session):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.skip_commit = False

def commit(self):
if self.skip_commit:
print("Commit skipped")
else:
super().commit()
```

- Session을 오버라이딩하여서 skip_commit이라는 플래그를 생성해준다.
- 그리고 skip_commit이 True일 때 커밋을 스킵하고 False이면 commit을 해준다.
- 그리고 Session을 만들 때 session maker에 해당 class를 지정해준다.

```python
SessionLocal = sessionmaker(... , class_=CustomSession)
```

- skip을 위한 Unit of Work를 만들어준다.

```python
class UnitOfWorkForSkip(AbstractUnitOfWork):
def __init__(self, db: Session):
self._db = db

def __enter__(self):
self._db.skip_commit = True
return self

def __exit__(self, *args):
print('rollback')
self._db.rollback()
self._db.close()

def commit(self):
try:
self._db.skip_commit = False
self._db.commit()
print('commit')
except SQLAlchemyError:
self.rollback()
raise TransactionFailException

def rollback(self):
self._db.rollback()
```

- 해당 UoW는 `__enter__`시 skip_commit을 True로 하여서 컨텍스트 내부에서 일어나는 commit을 전부 스킵해준다.
- 그리고 `commit()`을 할 때 skip_commit 플래그를 다시 False로 바꿔줘서 실제 commit이 가능하게 만들어주고, commit을 진행한다.
- 커밋도중 오류가 나면 rollback을 시키고 예외를 발생시킨다. 마찬가지로 컨텍스트에서 빠져나갈 때 `commit()`을 명시하지 않았다면 rollback을 진행하고 세션을 종료시킨다.
- 사용 예시는 다음과 같다

```python
with UnitOfWorkForSkip(session) as uow
insertLogic1(session)
insertLogic2(session)
uow.commit()
```

- 이렇게 기존 코드에 적용하면 해당 skip uow를 사용하지 않은 코드들도 영향이 가지 않은 채로 레거시를 현명하게 대처할 수 있다.

0 comments on commit 5a88f53

Please sign in to comment.