> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 트랜잭션 쓰기

> PlayFab Statistics 트랜잭션 쓰기를 사용하여 여러 플레이어 통계를 원자적으로 업데이트하고 진행 상황 업데이트 전반에서 일관성을 유지하세요.

# 트랜잭션 쓰기

이 튜토리얼에서는 통계에 대한 트랜잭션 쓰기를 수행하는 방법을 설명합니다. 통계를 저장하는 데
사용되는 프로세스에 따라, 개발자는 특히 SUM 집계에서 작업이 중복될 수 있는
시나리오에 직면할 수 있습니다. 이러한 복잡한 시나리오를 해결하기 위해 트랜잭션 쓰기 기능을 추가했습니다.

동시에 많은 매치가 진행되는 멀티플레이어 게임을 예로 시작하겠습니다.
이 게임은 각 매치에 대해 많은 수의 통계와 기타 telemetry 값을 저장합니다. 플레이어 경험을
방해하지 않기 위해 스튜디오는 실시간 대신 10분마다 통계를 푸시하기로 결정했습니다.

이 접근 방식은 한 매치에서 다른 매치로 이동하는 플레이어에게 원활한 경험을 보장합니다. 그러나
새로운 기술적 과제를 야기합니다. 이제 10분마다 요청을 실행할 큐가 필요합니다. 하지만
어떤 이유로든 큐의 이벤트를 재생하려는 경우 어떻게 될까요? 이 경우 특히 SUM 집계 통계를 가지고 있다면
이중 계산을 피해야 하기 때문에 어려움이 있을 수 있습니다.

이러한 맥락을 염두에 두고 이 특정 문제를 해결하는 방법을 보여드리겠습니다.

## 통계 정의 생성

먼저 통계 정의를 생성하는 것으로 시작하겠습니다. 이 수준에서는 트랜잭션 쓰기에 대한 특별한
구성을 추가할 필요가 없습니다.

```C# theme={null}
public static async Task CreateStatisticDefinitionAsync(PlayFabAuthenticationContext context, string statName)
{
    PlayFabProgressionInstanceAPI statsAPI = new PlayFabProgressionInstanceAPI(context);
    CreateStatisticDefinitionRequest statDefinitionRequest = new CreateStatisticDefinitionRequest()
    {
        Name = statName,
        AuthenticationContext = context,
        EntityType = "title_player_account",
        VersionConfiguration = new VersionConfiguration()
        {
            MaxQueryableVersions = 1,
            ResetInterval = ResetInterval.Manual,
        },
        Columns = new List<StatisticColumn>()
        {
            new StatisticColumn()
            {
                Name = "Eliminations",
                AggregationMethod = StatisticAggregationMethod.Sum,
            },
             new StatisticColumn()
            {
                Name = "Caliber",
                AggregationMethod = StatisticAggregationMethod.Min,
            }
        },
    };
    
    PlayFabResult<PlayFab.LeaderboardsModels.EmptyResponse> createStatDefResult = await statsAPI.CreateStatisticDefinitionAsync(statDefinitionRequest);
}
```

## 통계에 데이터 추가

이 예제를 계속하여, 이전에 정의한 통계에 데이터를 추가합니다. 일반 요청과 이 요청의 주요
차이점은 특별한 `TransactionId` 매개변수입니다. 이 매개변수는 실행 중인 요청의
식별자 역할을 합니다. 새 요청이 도착할 때마다, 시스템은 새 트랜잭션 ID를 이미 처리된 식별자와
비교합니다. 일치하는 항목이 발견되면 요청은 실행되지 않습니다.

고려해야 할 한 가지 핵심 사항은 이 트랜잭션 동작이 요청 내의 개별 통계가 아닌 `TransactionId`와
실행 중인 요청 간의 관계를 설정한다는 것입니다.
각 개별 통계에 대한 매핑이 있는 것이 아니라, 매핑은 전체 요청에 대한 것입니다. 또한 이 기능이 사용될 때는
이 유형의 요청을 추적하기 위한 다른 미터가 있으므로 여기에서 자세히 알아보세요: [Statistics 미터](/services/playfab/pricing/meters/statistics-meters)

```C# theme={null}
public static async Task UpdateStatisticForPlayer(PlayFabAuthenticationContext context, string statName, string entityId, int eliminationScore, int caliberScore)
{
    PlayFabProgressionInstanceAPI statsAPI = new PlayFabProgressionInstanceAPI(context);
    UpdateStatisticsRequest updateStatRequest = new UpdateStatisticsRequest()
    {
        Entity = new PlayFab.LeaderboardsModels.EntityKey()
        {
            Id = entityId,
            Type = EntityType
        },
        AuthenticationContext = context,
        TransactionId = "YOUR_OWN_IDENTIFIER"
        Statistics = new List<PlayFab.LeaderboardsModels.StatisticUpdate>() 
        {
            new PlayFab.LeaderboardsModels.StatisticUpdate() 
            {
                Name = statName,
                Scores = new List<string> { eliminationScore.ToString(), caliberScore.ToString()},
            }
        }
    };

    PlayFabResult<UpdateStatisticsResponse> updateResult = await statsAPI.UpdateStatisticsAsync(updateStatRequest);
}
```

이제 이 예제의 몇 가지 주요 요소를 설명하겠습니다:

* `Entity`: 이 매개변수는 통계를 업데이트하려는 대상 엔터티에 해당합니다.
* `TransactionId`: 이 매개변수는 요청의 고유 식별자를 나타내는 문자열에 해당합니다.
* `Statistics`: 이 매개변수는 엔터티의 실제 통계 집합에 해당합니다.
* `StatisticUpdate`: 이 매개변수는 추가할 통계 값에 해당합니다.
  * `Scores`: 이 매개변수는 하나의 엔터티에 추가할 수 있는 점수 목록에 해당합니다. 통계에는 둘 이상의 열이 있을 수 있음을 기억하세요.
    이러한 개념에 대한 자세한 내용은 여기에서 확인할 수 있습니다: [통계로 더 많은 작업하기](/services/playfab/player-progression/statistics/doing-more-statistics)
  * `Name`: 이 매개변수는 통계 정의를 생성할 때 설정한 통계 이름에 해당합니다.

이러한 개념을 명확히 이해했다면, 이제 통계에 데이터를 추가하고 요청 중복을 피할 준비가 되었습니다.

## 참고 자료

* [기본 통계 만들기](/services/playfab/player-progression/statistics/create-basic-statistics).
* [통계로 더 많은 작업하기](/services/playfab/player-progression/statistics/doing-more-statistics).
* [시즌별 통계](/services/playfab/player-progression/statistics/seasonal-statistics).
* [통계에 컨텍스트 데이터 추가](/services/playfab/player-progression/statistics/metadata-statistics).
* [API 참조](/services/playfab/player-progression/statistics/api-reference).
* [제한](/services/playfab/player-progression/statistics/limits-statistics).
* [할당량](/services/playfab/player-progression/statistics/quota-statistics)
* [Statistics 미터](/services/playfab/pricing/meters/statistics-meters).


## Related topics

- [메타데이터 통계](/ko/services/playfab/player-progression/statistics/metadata-statistics.md)
- [통계로 더 많은 작업 수행](/ko/services/playfab/player-progression/statistics/doing-more-statistics.md)
- [기본 통계 만들기](/ko/services/playfab/player-progression/statistics/create-basic-statistics.md)
- [시즌별 통계](/ko/services/playfab/player-progression/statistics/seasonal-statistics.md)
- [통계 제한 사항](/ko/services/playfab/player-progression/statistics/limits-statistics.md)
