객체 지향 패러다임의 전반적인 목적은 구현 세부사항을 캡슐화하는 것입니다. 따라서 지속성 관점에서 지속적 오브젝트가 임시 오브젝트와 동일하게 보이게 하려고 합니다. 오브젝트가 지속적인지
인식하거나 기타 오브젝트를 처리하는 방법과 다르게 오브젝트를 처리할 필요는 없습니다. 최소한 이를 목적으로 합니다.
실제로는 응용프로그램이 다음과 같이 다양한 지속성의 측면을 제어할 필요가 있을 수 있습니다.
-
지속적 오브젝트를 읽고 쓰는 시기
-
지속적 오브젝트가 삭제되는 시기
-
트랜잭션을 관리하는 방법
-
잠금 및 동시 제어를 달성하는 방법
여기에 연관된 두 가지 경우가 있습니다. 즉, 오브젝트가 지속적 오브젝트 스토어에 쓰는 초기 시기 및 응용프로그램이 오브젝트 변경에 따라 지속적 오브젝트 스토어를 갱신해야 하는 후속 시기가 그것입니다.
두 경우 모두 특정 메커니즘은 지속성 프레임워크에서 지원되는 오퍼레이션에 따라 달라집니다. 일반적으로 메시지를 지속성 프레임워크로 송신하여 지속적 오브젝트를 작성하는 메커니즘이 사용됩니다. 오브젝트가 지속적인 경우
지속성 프레임워크는 지속적 오브젝트의 후속 변경을 발견할 수 있고 필요한 경우 지속적 오브젝트 스토어에 필요한 변경을 작성합니다(일반적으로 트랜잭션이 확약될 때).
작성되는 지속적 오브젝트의 예제가 아래에 표시됩니다.
PersistenceMgr 오브젝트는 지속성 프레임워크인 VBOS의 인스턴스입니다. OrderCoordinator는 지속적 주문을 'createPersistentObject' 메시지의 인수로
PersistenceMgr에 송신하여 지속적 주문을 작성합니다.
이벤트의 어떤 시퀀스의 특정 위치에 오브젝트가 명시적으로 저장되는지 알아야 하는 경우가 아니라면 일반적으로 명시적으로 이를 모델링하지 않아도 됩니다. 서브시퀀스 오퍼레이션에서 오브젝트를 조회해야 하는
경우 오브젝트는 반드시 데이터베이스에 있어야 하기 때문에 오브젝트가 데이터베이스에 있음을 알아야 합니다.
지속적 오브젝트 스토어에서의 오브젝트 검색은 응용프로그램이 해당 오브젝트에 메시지를 송신하기 전에 수행해야 합니다. 객체 지향 시스템에서 해당 작업 재호출은 오브젝트로 메시지를 송신하여 수행됩니다. 그러나 메시지를
송신하려는 오브젝트가 데이터베이스에는 있지만 아직 메모리에는 없는 경우 문제가 발생합니다. 존재하지 않는 상황에서는 메시지를 송신할 수 없습니다.
다시 말해 데이터베이스에서 조회하는 방법을 아는 오브젝트에 메시지를 송신하고 올바른 오브젝트를 검색하며 이를 인스턴스화해야 합니다. 이렇게 해야만 원래 송신하려던 원본 메시지를 송신할 수 있게 됩니다. 지속적
오브젝트의 인스턴스를 작성하는 오브젝트는 팩토리 오브젝트라고도 합니다. 팩토리 오브젝트는 지속적 오브젝트를 포함하는 오브젝트의 인스턴스 작성을 책임집니다. 주어진 조회에 대해
팩토리는 조회에 일치하는 하나 이상의 오브젝트 세트를 리턴하도록 디자인될 수 있습니다.
일반적으로 오브젝트는 연관을 통해 서로 연결되므로, 일반적으로 오브젝트 그래프의 루트 오브젝트만 검색하면 됩니다. 나머지는 루트 오브젝트와의 연관을 통해 데이터베이스에서 필요한 오브젝트가 투명하게
'풀(pull)'됩니다. (유용한 지속성 메커니즘에서는 이를 현명하게 처리합니다. 즉, 필요한 경우에만 오브젝트를 검색하는데 이렇게 하지 않으면 많은 수의 오브젝트를 불필요하게 인스턴스화할 수 있습니다. 필요하기도
전에 오브젝트를 검색하는 것은 극단적으로 단순화된 지속성 메커니즘으로 발생하는 주요 성능 문제점 중 하나입니다.)
다음 예제에서는 지속적 오브젝트에서 오브젝트를 검색하여 모델링하는 방법을 보여줍니다. 실제 시퀀스 다이어그램에서 DBMS는 팩토리 오브젝트로 캡슐화되기 때문에 표시되지 않습니다.
지속적 오브젝트의 문제점은 지속성입니다. 임시 오브젝트를 작성한 프로세스가 종료되면 임시 오브젝트도 사라지는 것과 달리, 지속적 오브젝트는 명시적으로 삭제될 때까지 계속 존재하게 됩니다. 그렇기 때문에 더 이상
사용하지 않을 경우에는 해당 오브젝트를 반드시 삭제해야 합니다.
그렇지만 이를 결정하기가 쉽지 않습니다. 오브젝트를 사용하는 하나의 응용프로그램이 완료되었다고 해서 현재와 미래의 모든 응용프로그램이 완료되는 것은 아닙니다. 또한 오브젝트에는 오브젝트에서 인식하지 못하는 많은
연관이 작성되어 있기 때문에 해당 오브젝트를 삭제해도 되는지 결정하기가 쉽지 않습니다.
디자인 시 이 내용은 상태 차트를 사용하여 시맨틱으로 표시됩니다. 오브젝트가 종료 상태가 되면 해제됨으로 표시될 수 있습니다. 그러면 지속적 클래스 구현을 책임지는 개발자가
상태 차트 정보를 참조하여 올바른 지속성 메커니즘 동작을 호출하여 오브젝트를 해제합니다. 유스 케이스 실현(realization) 디자이너는 올바른 오퍼레이션을 호출하여 오브젝트가 삭제 가능한 상태가 되면 해당
오브젝트를 종료 상태가 되도록 해야 합니다.
오브젝트가 기타 오브젝트에 연결된 경우 오브젝트 삭제를 결정하기가 쉽지 않습니다. 팩토리 오브젝트는 오브젝트 구조 및 연결된 오브젝트를 알고 있으므로, 클래스의 팩토리 오브젝트를 특정 인스턴스 삭제
결정에 사용하면 유용한 경우가 있습니다. 지속성 프레임워크도 이 기능을 지원합니다.
트랜잭션은 원자인 오퍼레이션 호출 세트를 정의하는데, 이는 모두 수행되거나 전혀 수행되지 않습니다. 지속성 관점에서 트랜잭션은 모두 수행되거나 전혀 수행되지 않는 오브젝트 세트의 변경 세트를
정의합니다. 트랜잭션은 일관성을 제공하여 오브젝트 세트가 하나의 일치된 상태에서 다른 상태로 이동하도록 합니다.
유스 케이스 실현(realization)에서 트랜잭션을 표시하는 여러 옵션이 있습니다.
-
텍스트 사용. 시퀀스 다이어그램의 여백에 스크립트를 사용하여 트랜잭션 경계가 다음과 같이 문서화될 수 있습니다. 이 방법은 단순하며 얼마든지 많은 수의 메커니즘을 아용하여 트랜잭션을 구현할 수
있게 해줍니다.
텍스트 어노테이션을 사용하여 트랜잭션 경계 표시.
-
명시적 메시지 사용. 사용 중인 트랜잭션 관리 메커니즘에서 명시적 메시지를 사용하여 트랜잭션을 시작하고 종료하는 경우 해당 메시지는 다음과 같이 시퀀스 다이어그램에 명시적으로 표시될 수
있습니다.
트랜잭션을 시작 및 중지하는 명시적 메시지를 표시하는 시퀀스 다이어그램
오류 조건 처리
트랜잭션에 지정된 모든 오퍼레이션이 수행 가능하지 않은 경우(일반적으로 오류가 발생한 경우) 트랜잭션은 중단되고 트랜잭션 중에 발생한 모든 변경이 취소됩니다. 예상 오류 조건은 주로 유스 케이스의 예외
이벤트 플로우를 표시합니다. 또는 시스템 장애로 인해 오류 조건이 발생하는 경우도 있습니다. 오류 조건도 상호작용에 문서화해야 합니다. 단순한 오류 및 예외는 발생한 상호작용에 표시 가능합니다. 복잡한 오류 및
예외는 자체 상호작용이 필요합니다.
특정 오브젝트의 실패 모드가 상태 차트에 표시될 수 있습니다. 해당 실패 모드 제어 처리의 조건부 플로우는 오류 또는 예외가 발생한 상호작용에 표시될 수 있습니다.
동시성은 트랜잭션 과정의 중요한 시스템 자원에 대한 액세스 제어를 설명합니다. 시스템을 일관된 상태로 유지하기 위해 트랜잭션에서는 시스템의 특정 핵심 자원에 대해 독점적인 액세스를 필요로 합니다. 독점적인
액세스에는 오브젝트 세트 읽기, 오브젝트 세트 쓰기 또는 오브젝트 세트 읽기 및 쓰기 둘 다를 지원하는 기능이 포함될 수 있습니다.
오브젝트 세트에 대해 액세스를 제한해야 하는 이유를 설명하는 단순한 예제를 살펴보겠습니다. 단순한 주문 입력 시스템을 실행 중이라고 가정해 보십시오. 고객의 전화 주문을 받으면 주문을 처리하고 주문을 배송합니다.
주문을 트랜잭션 유형으로 볼 수 있습니다.
동시성 제어의 필요성을 보여주기 위해, 하이킹 부츠를 전화로 주문했다고 가정해 보십시오. 주문이 시스템에 입력되면 시스템은 주문한 하이킹 부츠에 해당하는 재고가 있는지 있는지 확인합니다. 해당하는 제품이 있는 경우
그 제품을 예약해서 주문이 배송되기 전에 다른 사람이 해당 제품을 구매하지 못하도록 합니다. 주문이 배송되고 나면 부츠가 재고에서 제거됩니다.
주문이 제출되고 운송될 때까지 부츠는 특수 상태(즉 재고에는 있지만 주문용으로 "확약"되어 있음)에 있습니다. 어떤 이유로 주문이 취소되는 경우(변심 또는 카드 만기) 부츠는 재고로 다시 돌아옵니다. 주문이
배송되면 회사에서는 해당 부츠의 레코드를 보관하지 않는다고 가정해 보십시오.
트랜잭션과 마찬가지로 동시성의 목적은 시스템이 하나의 일관된 상태에서 다른 상태로 이동되도록 하는 것입니다. 또한 동시성은 트랜잭션에 작업 완료에 필요한 모든 자원이 포함되도록 합니다. 동시성 제어는 자원 잠금,
세마포어, 공유 메모리 래치 및 개인용 작업공간을 포함하여 다양한 여러 방식으로 구현됩니다.
객체 지향 시스템에서 메시지 패턴만으로 특정 메시지가 오브젝트의 상태를 변경했는지를 알기는 힘듭니다. 또한, 다른 구현은 자원의 특정 유형에 대한 액세스를 제한해야 하는 필요가 애초에 없어집니다. 예를 들어 몇몇
구현에서는 트랜잭션 초반에 시스템 상태에 대한 자체 보기를 각 트랜잭션에 제공합니다. 이 경우 기타 프로세스는 다른 트랜잭션 실행 '보기'에 영향을 주지 않으면서 오브젝트의 상태를 변경할 수도 있습니다.
구현 제한을 막기 위해 디자인 시 트랜잭션이 독점적으로 액세스해야 하는 자원을 표시할 수 있습니다. 위 예제의 경우, 주문한 부츠에 독점 액세스가 필요함을 표시하고자 할 수 있습니다. 단순한 대안으로, 송신 중의
메시지 설명에 어노테이션을 추가하여 응용프로그램이 오브젝트에 독점적으로 액세스해야 함을 표시합니다. 그러면 구현자는 이 정보를 참조하여 동시성 요구사항 구현의 최선책을 결정합니다. 독점적인 액세스를 필요로 하는
메시지의 어노테이션을 표시하는 시퀀스 다이어그램 예제가 아래 표시됩니다. 예제에서는 트랜잭션이 완료되면 모든 잠금이 해제되는 것으로 간주됩니다.
시퀀스 다이어그램에 어노테이션이 있는 액세스 제어 표시 예제.
트랜잭션에서 필요한 모든 오브젝트에 액세스를 제한하지 않는 이유는 소수의 오브젝트에만 액세스가 제한되는 경우가 있기 때문입니다. 트랜잭션에 참여하는 모든 오브젝트의 액세스를 제한하면 중요한 자원이 낭비될 수 있고
성능 병목 현상이 예방되는 것이 아니라 오히려 발생될 수 있습니다.
|