다음을 통해 공유


Resource Manager 만들기

리소스 관리자는 각 트랜잭션의 데이터를 유지하고 트랜잭션의 작업을 기록합니다. TPS(트랜잭션 처리 시스템)에 여러 리소스 관리자가 있는 경우 각 리소스 관리자는 각 트랜잭션의 커밋, 롤백 및 복구 작업에 참여할 수 있습니다.

각 리소스 관리자는 트랜잭션 클라이언트가 리소스 관리자가 유지 관리하는 데이터베이스 또는 기타 리소스에 액세스하는 데 사용할 수 있는 인터페이스를 내보내야 합니다.

일반적으로 커널 모드 리소스 관리자는 나열된 순서대로 다음 작업을 수행해야 합니다.

  1. 로그 스트림을 만듭니다.

    리소스 관리자는 CLFS( Common Log File System ) 또는 다른 로깅 기능을 사용하여 로그 스트림을 유지할 수 있습니다. ClfsCreateLogFile에 대한 호출은 CLFS 로그 스트림을 만듭니다. 리소스 관리자는 로그 스트림을 사용하여 트랜잭션을 커밋, 롤백 또는 복구하는 데 필요한 정보를 기록해야 합니다. 또한 KTM은 로그 스트림을 사용하여 트랜잭션을 복구하는 데 필요할 수 있는 내부 상태 변경 내용을 기록합니다.

  2. 트랜잭션 관리자 개체를 만듭니다.

    ZwCreateTransactionManager에 대한 호출은 트랜잭션 관리자 개체를 만들고 리소스 관리자가 지정하는 추가 CLFS 로그 스트림에 리소스 관리자를 연결합니다.

  3. 트랜잭션 관리자 상태를 복구합니다.

    ZwRecoverTransactionManager에 대한 호출은 트랜잭션 관리자 개체의 로그 스트림(KTM이 유지 관리)을 읽고 모든 트랜잭션이 완료되기 전에 TPS가 종료되었는지 여부를 확인합니다(예: 시스템이 충돌했기 때문). KTM은 로그 스트림의 정보를 기반으로 내부 상태를 복원합니다.

  4. 리소스 관리자 개체를 만듭니다.

    ZwCreateResourceManager에 대한 호출은 리소스 관리자 개체를 만들고 이전에 만든 트랜잭션 관리자 개체와 연결합니다.

  5. 리소스 관리자 상태를 복구합니다.

    ZwRecoverResourceManager를 호출하면 KTM이 리소스 관리자를 마지막으로 종료했을 때 진행 중인 모든 트랜잭션에 대한 알림을 TRANSACTION_NOTIFY_RECOVER 리소스 관리자를 보냅니다. 리소스 관리자가 이러한 알림에 응답하는 방법에 대한 자세한 내용은 복구 작업 처리를 참조하세요.

  6. 클라이언트에서 트랜잭션을 수신합니다.

    일반적으로 클라이언트는 트랜잭션 개체를 만들고 리소스 관리자의 클라이언트 인터페이스를 사용하여 트랜잭션 개체의 GUID를 리소스 관리자에 전달합니다. 예를 들어 리소스 관리자는 TPS 구성 요소 이해 항목에서 설명하는 것과 유사한 CreateDataObject 루틴을 제공할 수 있습니다.

  7. 각 트랜잭션에 등록합니다.

    ZwOpenTransaction을 호출하면 트랜잭션 개체에 대한 핸들이 열리고 ZwCreateEnlistment를 호출하면 트랜잭션에 대한 인리스트먼트가 만들어집니다. 인리스트먼트를 사용하면 리소스 관리자가 지정된 트랜잭션 알림 집합을 받을 수 있습니다.

  8. 트랜잭션 알림 수신을 사용하도록 설정합니다.

    리소스 관리자는 ZwGetNotificationResourceManager 를 호출하여 알림을 동기적으로 가져오거나 TmEnableCallbacks 를 호출하여 알림을 사용할 수 있을 때마다 KTM이 호출하는 ResourceManagerNotification 콜백 루틴을 등록할 수 있습니다.

  9. 클라이언트의 서비스 리소스 액세스 요청이지만 변경 내용을 영구적으로 만들지는 않습니다.

    클라이언트가 트랜잭션 개체를 만든 후에는 일반적으로 리소스 관리자의 인터페이스를 호출하여 리소스 관리자의 리소스에 액세스합니다. 예를 들어 데이터베이스의 리소스 관리자는 데이터베이스에서 읽고 데이터베이스에 쓸 요청을 받을 수 있습니다.

    리소스 관리자는 트랜잭션 작업이 커밋, 롤백 또는 복구될 것이라는 알림을 받을 때까지 CLFS 로그 스트림 또는 기타 로깅 기능에 읽기 및 쓰기 작업의 결과를 기록해야 합니다.

  10. 클라이언트 작업을 커밋하거나 롤백합니다.

    결국 리소스 관리자는 클라이언트가 수행한 작업 커밋 또는 롤백을 시작하는 알림을 받습니다. 이에 대한 응답으로 리소스 관리자는 클라이언트 작업을 영구적으로 만들거나 삭제해야 합니다. 커밋 및 롤백 알림을 처리하는 방법에 대한 자세한 내용은 트랜잭션 작업 처리를 참조하세요.

    경우에 따라 리소스 관리자가 디바이스가 깜짝 제거되었다고 판단했기 때문에 KTM이 커밋 또는 롤백 알림을 신속하게 제공하도록 강제해야 할 수 있습니다. 이러한 경우 리소스 관리자는 TmRequestOutcomeEnlistment를 호출할 수 있습니다.

  11. 인리스트먼트 개체 핸들을 닫습니다.

    리소스 관리자가 트랜잭션 처리를 완료한 후 ZwClose 를 호출하여 인리스트먼트 개체의 핸들을 닫아야 합니다.

  12. Resource Manager 개체 핸들 및 트랜잭션 관리자 개체 핸들을 닫습니다.

    리소스 관리자가 언로드하기 전에 ZwClose 를 호출하여 리소스 관리자 개체의 핸들과 트랜잭션 관리자 개체의 핸들을 닫아야 합니다.

1~5단계는 리소스 관리자의 초기화 코드에서 수행해야 합니다. 예를 들어 리소스 관리자가 커널 모드 드라이버인 경우 초기화 코드는 드라이버의 DriverEntry 루틴입니다.

6~11단계는 일반적으로 트랜잭션 클라이언트의 요청에 응답하는 코드에서 수행됩니다.

12단계는 커널 모드 드라이버의 언로드 루틴과 같은 리소스 관리자의 최종 클린 코드에서 수행해야 합니다.

Read-Only 인리스트먼트 만들기

읽기 전용 인리스트먼트는 KTM에서 알림을 받지 않는 인리스트먼트입니다. 리소스 관리자는 ZwReadOnlyEnlistment를 호출하여 모든 인리스트먼트를 읽기 전용으로 만들 수 있습니다. 이 호출로 인해 KTM이 리소스 관리자에게 알림 배달을 중지합니다.

리소스 관리자가 ZwCreateEnlistment를 호출한 후 ZwPrepareComplete를 일반적으로 호출할 때까지 언제든지 ZwReadOnlyEnlistment를 호출할 수 있습니다.

리소스 관리자가 ZwReadOnlyEnlistment를 호출하도록 할 수 있는 두 가지 이유가 있습니다.

  • 리소스 관리자가 트랜잭션에 참여했으며, TRANSACTION_NOTIFY_COMMIT 알림을 받기 전에 리소스 관리자는 더 이상 트랜잭션의 커밋 작업에 참여할 필요가 없다고 결정합니다.

    예를 들어 리소스 관리자가 TRANSACTION_NOTIFY_PREPARE 알림을 받으면 트랜잭션 작업이 리소스 관리자의 데이터베이스를 변경하지 않은 것을 확인할 수 있습니다. 리소스 관리자는 ZwPrepareComplete 대신 ZwReadOnlyEnlistment를 호출하여 트랜잭션에서 자신을 제거할 수 있습니다.

  • 리소스 관리자는 트랜잭션의 커밋 작업에 참여하지 않습니다.

    예를 들어 리소스 관리자는 저장된 데이터베이스를 수정하지 않고 클라이언트가 보내는 데이터를 모니터링할 수 있습니다. 이 경우 리소스 관리자는 ZwCreateEnlistment 를 호출한 직후 ZwReadOnlyEnlistment를 호출할 수 있습니다. 또한 이 항목의 다음 섹션에 설명된 대로 이러한 리소스 관리자를 휘발성으로 만들도록 선택할 수 있습니다.

리소스 관리자가 ZwReadOnlyEnlistment를 호출한 후 ZwClose 를 호출하여 인리스트먼트 핸들을 닫을 수 있습니다.

Volatile-Resource 관리자 만들기

volatile-resource Manager는 지속성 데이터를 유지 관리하지 않는 리소스 관리자입니다. 예를 들어 리소스 관리자가 지속적으로 저장된 데이터베이스를 수정하지 않는 경우 클라이언트가 보내는 데이터를 모니터링하는 volatile-resource Manager를 만들 수 있습니다. Volatile-resource 관리자는 일반적으로 트랜잭션 작업을 기록하지 않으므로 복구 또는 롤백 작업을 수행할 수 없습니다.

volatile-resource 관리자는 ZwCreateResourceManager를 호출할 때 RESOURCE_MANAGER_VOLATILE 플래그를 설정해야 합니다. 이 플래그가 설정되면 KTM은 연결된 트랜잭션 관리자 개체의 로그 스트림에서 리소스 관리자에 대한 정보를 기록하지 않습니다.

리소스 관리자는 ZwCreateTransactionManager를 호출할 때 TRANSACTION_MANAGER_VOLATILE 플래그를 설정할 수도 있습니다. 이 플래그가 설정되면 KTM은 트랜잭션 관리자 개체에 대한 로그 스트림을 만들지 않습니다. 또한 트랜잭션 관리자 개체에 연결된 추가 리소스 관리자도 휘발성이어야 하며 RESOURCE_MANAGER_VOLATILE 플래그를 설정해야 합니다.

기존 TPS에 Resource Manager 추가

기존 TPS에 추가 리소스 관리자를 추가해야 하는 경우 다음 두 가지 옵션이 있습니다.

  • 새 리소스 관리자는 ZwCreateTransactionManager 를 호출하여 자체 트랜잭션 관리자 개체를 만듭니다.

    리소스 관리자가 TPS의 다른 리소스 관리자와 통신하지 않는 경우 이 옵션을 사용합니다.

  • 새 리소스 관리자는 ZwOpenTransactionManager 를 호출하여 기존 트랜잭션 관리자 개체에 연결합니다.

    리소스 관리자가 TPS의 다른 리소스 관리자와 통신해야 하는 경우 이 선택을 사용합니다. ZwCreateTransactionManager를 호출하는 리소스 관리자는 다른 리소스 관리자가 ZwOpenTransactionManager를 호출할 수 있도록 트랜잭션 관리자 개체의 GUID, 로그 스트림 이름 또는 개체 이름을 공유해야 합니다. 이러한 다른 리소스 관리자는 ZwQueryInformationTransactionManager 를 호출하여 트랜잭션 관리자 개체에 대한 추가 정보를 가져올 수 있습니다.

리소스 관리자를 TPS에 추가한 후 리소스 관리자를 알고 있는 클라이언트는 리소스 관리자의 클라이언트 인터페이스를 호출할 수 있습니다.