다음을 통해 공유


TPS 구성 요소 이해

KTM(커널 트랜잭션 관리자) 및 CLFS(공용 로그 파일 시스템)를 사용하는 모든 TPS(트랜잭션 처리 시스템)에는 다음과 같은 중요한 구성 요소가 포함되어야 합니다.

  • 트랜잭션 관리자(KTM)

    KTM은 각 트랜잭션의 상태를 추적하고 시스템 충돌 후 복구 작업을 조정합니다.

  • 하나 이상의 리소스 관리자

    사용자가 제공하는 리소스 관리자는 각 트랜잭션과 연결된 데이터를 관리합니다.

  • 하나 이상의 CLFS 로그 스트림

    트랜잭션 관리자 및 리소스 관리자는 CLFS 로그 스트림을 사용하여 트랜잭션을 커밋, 롤백 또는 복구하는 데 사용할 수 있는 정보를 기록합니다.

  • 하나 이상의 트랜잭션 클라이언트

    일반적으로 TPS의 각 트랜잭션 클라이언트는 트랜잭션을 만들고, 트랜잭션 컨텍스트 내에서 데이터에 대한 작업을 수행한 다음, 트랜잭션에 대한 커밋 또는 롤백 작업을 시작할 수 있습니다.

이 항목에서는 하나의 리소스 관리자가 있는 간단한 TPS , 여러 리소스 관리자를 포함하는 보다 복잡한 TPS 및 다른 TPS 시나리오를 소개합니다.

KTM 사용 섹션에서는 KTM을 사용하여 TPS 구성 요소를 만드는 방법에 대한 자세한 정보를 제공합니다.

단순 TPS

간단한 TPS는 KTM, 하나의 리소스 관리자 및 CLFS로 구성될 수 있습니다. 트랜잭션 클라이언트는 리소스 관리자가 제공하는 인터페이스를 통해 리소스 관리자와 통신할 수 있습니다.

예를 들어 데이터베이스 관리 시스템을 만들려는 경우를 가정해 보겠습니다. 시스템의 클라이언트가 데이터베이스 개체에 대한 핸들을 열고 개체에 대한 읽기 및 쓰기 작업을 수행한 다음 개체 핸들을 닫아 데이터베이스에 액세스하려고 합니다.

이제 시스템의 다른 사용자가 최종 결과만 볼 수 있도록 읽기 및 쓰기 작업 집합이 원자성으로 수행되도록 하려는 경우를 가정해 보겠습니다. 클라이언트가 데이터베이스 작업 집합을 트랜잭션에 바인딩할 수 있도록 하는 TPS를 설계하여 이 목표를 달성할 수 있습니다.

시스템에는 클라이언트의 읽기 및 쓰기 요청에 대한 응답으로 데이터베이스의 데이터를 관리하는 리소스 관리자가 포함되어야 합니다. 이 리소스 관리자는 클라이언트가 트랜잭션을 읽기 및 쓰기 작업 집합과 연결할 수 있도록 하는 API(애플리케이션 프로그래밍 인터페이스)를 내보낼 수 있습니다.

리소스 관리자가 로드되면 ZwCreateTransactionManagerZwCreateResourceManager를 호출하여 KTM에 등록해야 합니다. 그런 다음, 리소스 관리자가 트랜잭션에 참여할 수 있습니다.

리소스 관리자가 클라이언트가 데이터 개체를 만들고, 데이터 개체와 연결된 데이터를 읽고 쓰고, 데이터 개체를 닫을 수 있도록 하는 함수 집합을 지원할 수 있습니다. 다음 의사 코드는 클라이언트의 예제 코드 시퀀스를 보여 줍니다.

CreateDataObject (IN TransactionID, OUT DataHandle);
ReadData (IN DataHandle, OUT Data);
WriteData (IN DataHandle, IN Data);
WriteData (IN DataHandle, IN Data);
WriteData (IN DataHandle, IN Data);
CloseDataObject (IN DataHandle);

클라이언트가 리소스 관리자의 CreateDataObject 루틴을 호출하려면 먼저 클라이언트가 KTM의 ZwCreateTransaction 루틴을 호출하여 트랜잭션 개체를 만들고 ZwQueryInformationTransaction을 호출하여 트랜잭션 개체의 식별자를 가져와야 합니다.

클라이언트가 리소스 관리자의 CreateDataObject 루틴을 호출하면 클라이언트는 트랜잭션 개체의 식별자를 리소스 관리자에 전달합니다. 리소스 관리자는 ZwOpenTransaction 을 호출하여 트랜잭션 개체에 대한 핸들을 가져온 다음 ZwCreateEnlistment 를 호출하여 트랜잭션 참여를 등록할 수 있습니다.

이 시점에서 클라이언트는 데이터 개체에 대한 작업을 시작할 수 있습니다. 클라이언트가 데이터 개체를 만들 때 트랜잭션 식별자를 제공했기 때문에 리소스 관리자는 모든 읽기 및 쓰기 작업을 트랜잭션에 할당할 수 있습니다.

리소스 관리자는 결과를 영구적으로 만들지 않고 클라이언트가 지정하는 데이터 작업의 모든 결과를 기록해야 합니다. 일반적으로 리소스 관리자는 CLFS를 사용하여 작업 결과를 트랜잭션 로그 스트림에 기록합니다.

클라이언트가 트랜잭션 작업을 수행하기 위해 리소스 관리자 호출을 완료하면 KTM의 ZwCommitTransaction 루틴을 호출합니다. 이 시점에서 KTM은 리소스 관리자에게 작업을 영구적으로 만들어야 한다고 수 있습니다. 그런 다음 리소스 관리자는 로그 스트림에서 데이터의 영구 스토리지 매체로 작업 결과를 이동합니다. 마지막으로 리소스 관리자는 ZwCommitComplete 를 호출하여 KTM에 커밋 작업이 완료되었다는 것을 알릴 수 있습니다.

리소스 관리자가 ReadData 또는 WriteData 에 대한 클라이언트 호출 중 하나에 대한 오류를 보고하면 어떻게 니까? 클라이언트는 ZwRollbackTransaction을 호출하여 트랜잭션을 롤백할 수 있습니다. 이 호출의 결과로 KTM은 리소스 관리자에게 데이터를 원래 상태로 복원해야 한다고 알 수 있습니다. 그런 다음 클라이언트는 동일한 작업에 대한 새 트랜잭션을 만들거나 계속하지 않도록 선택할 수 있습니다.

다음 의사 코드는 클라이언트의 트랜잭션 작업의 보다 자세한 시퀀스의 예를 보여 줍니다.

    ZwCreateTransaction (&TransactionHandle, ...);
    ZwQueryInformationTransaction (TransactionHandle, ...);
    CreateDataObject (TransactionID, &DataHandle);
    Status = ReadData (DataHandle, &Data1);
    if (Status == Error) goto ErrorRollback;
    Status = WriteData (DataHandle, Data2);
    if (Status == Error) goto ErrorRollback;
    Status = WriteData (DataHandle, Data3);
    if (Status == Error) goto ErrorRollback;
    Status = WriteData (DataHandle, Data4);
    if (Status == Error) goto ErrorRollback;
    ZwCommitTransaction (TransactionHandle, ...);
    goto Leave;
ErrorRollback:
    ZwRollbackTransaction (TransactionHandle, ...);
Leave:
    ZwClose (TransactionHandle);
    return;

트랜잭션을 만든 후 커밋되거나 롤백되기 전에 시스템이 충돌하면 어떻게 되나요? 리소스 관리자가 로드할 때마다 ZwRecoverTransactionManagerZwRecoverResourceManager를 호출해야 합니다. ZwRecoverTransactionManager를 호출하면 KTM이 로그 스트림을 열고 트랜잭션 기록을 읽습니다. ZwRecoverResourceManager를 호출하면 KTM이 충돌 전에 진행 중이고 리소스 관리자가 복구해야 하는 트랜잭션에 대해 리소스 관리자에게 알립니다.

크래시 전에 트랜잭션에 대해 ZwCommitTransaction 이라는 트랜잭션 클라이언트가 트랜잭션에 대한 커밋 작업을 처리하기 시작한 경우 리소스 관리자는 트랜잭션 상태를 크래시 직전에 지점으로 복원할 수 있어야 합니다. 클라이언트가 크래시 전에 트랜잭션을 커밋할 준비가 되지 않은 경우 리소스 관리자는 데이터를 삭제하고 트랜잭션을 롤백할 수 있습니다.

트랜잭션 클라이언트를 작성하는 방법에 대한 자세한 내용은 트랜잭션 클라이언트 만들기를 참조하세요.

리소스 관리자를 작성하는 방법에 대한 자세한 내용은 Resource Manager 만들기를 참조하세요.

TPS의 여러 리소스 관리자

이제 TPS를 사용하면 클라이언트가 단일 트랜잭션 내의 두 개의 개별 데이터베이스에 있는 정보를 수정할 수 있으므로 두 데이터베이스의 수정이 성공한 경우에만 트랜잭션이 성공한다고 가정합니다.

이 경우 TPS에는 각 데이터베이스에 대해 하나씩 두 개의 리소스 관리자가 있을 수 있습니다. 각 리소스 관리자는 클라이언트가 리소스 관리자의 데이터베이스에 액세스하는 데 사용할 수 있는 API를 내보낼 수 있습니다.

다음 의사 코드는 클라이언트가 두 리소스 관리자가 지원하는 두 데이터베이스에 대한 작업을 포함하는 단일 트랜잭션을 만드는 방법을 보여 줍니다.

이 예제에서 클라이언트는 첫 번째 데이터베이스에서 데이터를 읽고 두 번째 데이터베이스에 씁니다. 그런 다음 클라이언트는 두 번째 데이터베이스에서 데이터를 읽고 첫 번째 데이터베이스에 씁니다. (첫 번째 리소스 관리자는 Rm1로 시작하는 함수를 내보내고 두 번째 리소스 관리자는 Rm2로 시작하는 함수를 내보냅니다.)

    ZwCreateTransaction (&TransactionHandle, ...);
    ZwQueryInformationTransaction (TransactionHandle, ...);
    Rm1CreateDataObject (TransactionID, &Rm1DataHandle);
    Rm2CreateDataObject (TransactionID, &Rm2DataHandle);
    Status = Rm1ReadData (Rm1DataHandle, &Rm1Data);
    if (Status == Error) goto ErrorRollback;
    Status = Rm2WriteData (Rm2DataHandle, Rm1Data);
    if (Status == Error) goto ErrorRollback;
    Status = Rm2ReadData (Rm2DataHandle, &Rm2Data);
    if (Status == Error) goto ErrorRollback;
    Status = Rm1WriteData (Rm1DataHandle, Rm2Data);
    if (Status == Error) goto ErrorRollback;
    ZwCommitTransaction (TransactionHandle, ...);
    goto Leave;
ErrorRollback:
    ZwRollbackTransaction (TransactionHandle, ...);
Leave:
    ZwClose (TransactionHandle);
    return;

클라이언트가 동일한 트랜잭션 식별자를 두 리소스 관리자에게 전달하기 때문에 두 리소스 관리자 모두 ZwOpenTransactionZwCreateEnlistment 를 호출하여 트랜잭션에 참가할 수 있습니다. 클라이언트가 결국 ZwCommitTransaction을 호출하면 KTM은 각 리소스 관리자에게 관리자가 작업을 영구적으로 만들어야 한다고 알리 고, 각 리소스 관리자는 작업이 완료되면 ZwCommitComplete 를 호출합니다.

기타 TPS 시나리오

KTM은 다른 TPS 시나리오를 지원합니다. 예를 들어 다음 시나리오에서는 TPS에 포함될 수 있는 구성 요소를 설명합니다.

  • 여러 데이터베이스를 관리하는 하나의 리소스 관리자입니다.

    리소스 관리자의 API를 사용하면 클라이언트가 한 번에 둘 이상의 데이터베이스를 열고 액세스할 수 있으며 클라이언트는 단일 트랜잭션에서 여러 데이터베이스에 대한 액세스를 결합할 수 있습니다.

  • 클라이언트가 호출하는 API가 있는 하나의 리소스 관리자와 첫 번째 리소스 관리자가 호출하는 API를 사용하는 추가 리소스 관리자.

    클라이언트는 첫 번째 리소스 관리자와만 통신합니다. 해당 리소스 관리자가 클라이언트의 요청을 처리할 때 필요에 따라 추가 리소스 관리자에 액세스하여 클라이언트의 요청을 처리할 수 있습니다. 예를 들어 리소스 관리자는 클라이언트에서 사용할 수 없는 두 번째 리소스 관리자의 백업 또는 데이터 확인 작업이 필요한 클라이언트 액세스 가능 데이터베이스를 관리합니다.

  • KTM을 사용하지 않는 기존 클라이언트 및 리소스 관리자는 KTM을 사용하는 추가 리소스 관리자 집합과 통합됩니다.

    이 경우 일반적으로 KTM과 통신하는 우수한 트랜잭션 관리자가 되도록 기존 리소스 관리자를 수정해야 합니다.