본문 바로가기

Design Patterns

작업단위 패턴

이 포스팅은 어플리케이션 아키텍쳐 패턴 11장을 요약한 내용입니다.

 

작업단위 - 트랜잭션 관리

비즈니스 트랜잭션의 영향을 받은 객체의 리스트를 유지 관리하고, 변경 내용을 기록하는 일과 동시성 문제를 해결하는 일을 조율한다.

 

작동원리

객체의 CUD (생성, 수정, 삭제)가 발생하면 데이터베이스에 기록해야한다. 작업 단위는 이러한 변경 내용을 추적하는 객체다. 데이터베이스에 영향을 미칠 수 있는 작업을 시작하면 작업 단위를 만들고 이러한 변경 내용을 추적해야 하며, 객체를 생성, 수정, 삭제할 때마다 이를 작업단위에 알려야 한다.

 

장점

  • 어플리케이션 프로그래머는 데이터베이스를 업데이트하는 메서드를 직접 실행할 필요가 없다.
  • 어플리케이션 프로그래머는 변경 내용을 직접 추적하거나 참조 무결성을 고려해 작업 순서를 조정할 필요가 없다.

커밋할 시점이 되면 무엇을 해야하는지 작업 단위가 직접 정한다.

 

세 가지 방식

1. 호출자 등록

  • 호출자가 직접 작업 단위에 등록하는 방식.
  • 등록하지 않은 객체의 변경 내용은 커밋할 때 기록되지 않는다.
  • 등록하는 것을 잊어버리면 내용이 손실되지만, 필요에 따라 등록하지 않을 수 있어서 유연하다.

 

2. 객체 등록

  • 등록 메서드를 객체 메서드에 넣는 방식.
  • 객체 개발자는 잊지 말고 적절한 위치에서 등록 메서드를 호출해야한다.
  • 관점 지향 프로그래밍을 활용하면 소스코드 수준에서 깔끔하게 문제를 해결할 수 있다.

 

3. 작업단위 컨트롤러 - 발전하면 지금 쓰고있는 방식(?)

  • 읽을 때 객체 복사본을 만들고 커밋할 때 복사본과 객체를 비교한다.

 

작업단위를 유용하게 사용할 수 있는 영역

  • 데이터베이스가 참조 무결성을 사용할 때 업데이트 순서를 조율해야 할 때
  • 교착 상태를 최소화 할 때 (순서 조율)
  • 일괄 업데이트를 처리할 때

사용시점

작업 단위는 우리가 조작한 다양한 객체를 추적해서 나중에 어떤 객체를 데이터베이스와 동기화해야 하는지 알수있게 해준다.

 

작업 단위 대안

1. 모든 객체를 명시적으로 저장한다.

문제점 : 필요 이상으로 데이터베이스 호출을 많이 하게 된다.

2. 모든 업데이트를 마지막으로 연기한다.

문제점 : 변경된 모든 객체를 추적해야 한다. (복잡해지면 관리하기 힘듦)

 

 

예제

class UnitOfWork{
	
	private List newObjects = new ArrayList();
	private List dirtyObjects = new ArrayList();
	private List removedObjects = new ArrayList();
    
    public void registerNew(DomainObject obj){
    	newObjects.add(obj);
    }
    
    public void registerDirty(DomainObject obj)...
    
    public void registerRemoved(DomainObject obj)...
    
    public void commit(){
    	insertNew();
        updateDirty();
        deleteRemoved();
    }
    
    private void insertNew(){
    	for (Iterator objects = newObjects.iterator(); objects.hasNext();){
        	DomainObject obj = (DomainObject) objects.next();
            MapperRegistry.getMapper(obj.getClass()).insert(obj);
        }
    }
    ...
}
class DomainObject...

	protected void markNew(){
    	UnitOfWork.getCurrent().registerNew(this);
    }
    
    protected void markClean(){
    	UnitOfWork.getCurrent().registerClean(this);
    }
    
    protected void markDirty(){
    	UnitOfWork.getCurrent().registerDirty(this);
    }
    
    protected void markRemoved(){
    	UnitOfWork.getCurrent().registerRemoved(this);
    }
    ...
class Album extends DomainObject...
	
    public static Album create(String name){
    	Album obj = new Album();
        obj.markNew();
        return obj;
    }
    
    public void setTitle(String title){
    	this.title = title;
        markDirty();
    }

'Design Patterns' 카테고리의 다른 글

게이트웨이 패턴, 서비스 스텁 패턴  (0) 2020.10.08
지연로드(Lazy Load) 패턴  (0) 2020.10.04
식별자 맵 패턴  (0) 2020.10.03
애그리거트 트랜잭션관리  (0) 2020.09.20
애그리거트  (0) 2020.09.12