트랜잭션 관련 오류 질문드립니다.

고객님의 문의에 답변하는 직원은 고객 여러분의 가족 중 한 사람일 수 있습니다.
고객의 언어폭력(비하, 조롱, 욕설, 협박, 성희롱 등)으로부터 직원을 보호하기 위해
관련 법에 따라 수사기관에 필요한 조치를 요구할 수 있으며, 형법에 의해 처벌 대상이 될 수 있습니다.

커뮤니티 이용 정책에 위배되는 게시물을 작성할 경우, 별도 안내 없이 게시물 삭제 또는 커뮤니티 이용이 제한될 수 있습니다.

문의 응대 : 평일 오전 10시 ~ 오후 6시
문의를 남기실 경우 다음 항목을 작성해 주세요.
정보가 부족하거나 응대시간 외 문의하는 경우 확인 및 답변이 지연될 수 있습니다.

  • 뒤끝 SDK 버전 : 5.11.6
  • 프로젝트명 : ProjectSam_Korea01
  • 스테이터스 코드 : 400
  • 에러 코드 : TransactionExceptionError
  • 에러 메시지 : Collection was modified; enumeration operation may not execute.

최근 로그를 살펴보던 중 error 항목에 해당 오류 로그가 많이 남은 것을 확인했습니다.
혹시 어떤 이유로 해당 오류가 발생하는 지 알 수 있을까요?

안녕하세요, 개발자님.
문의하신 내용 상세 확인을 위해 몇 가지 정보를 요청드립니다.
오류가 발생하고 있는 코드 조각과,
리스트 / 딕셔너리를 루프 하여 안에 엔티티를 삭제하는 코드가 없는지 확인해 주시면 감사드리겠습니다.

안녕하세요.
요청해주신 트랜잭션을 요청하는 코드 조각입니다.
해당 코드 내에서 딕셔너리를 루프하는 코드는 코드 아래쪽에 첨부한
'GoodTemp’를 만들 때 이외에는 없는 것으로 확인했습니다.
혹시 더 확인이 필요한 부분이 있으면 이야기 부탁드리겠습니다.

List<TransactionValue> transactionList = new List<TransactionValue>();

// 변경된 데이터만큼 트랜잭션 추가
foreach (var gameData in gameDatas)
{
    transactionList.Add(gameData.GetTransactionUpdateValue());
}

// 콜백이 60초내에 정상적으로 왔는지 체크
CancellationTokenSource cts = new CancellationTokenSource();
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
cts.CancelAfter(TimeSpan.FromSeconds(60));

// 트랜잭션 요청
SendQueue.Enqueue(Backend.GameData.TransactionWriteV2, transactionList, callback => {
    Debug.Log($"Backend.BMember.TransactionWriteV2 : {callback}");

    if (callback.IsSuccess())
    {
        tcs.TrySetResult(true);
    }
    else
    {
        tcs.TrySetResult(false);
    
        Debug.Log("저장 실패");

        // ..... 게임 종료 로직
    }
});

try
{
    // Task가 완료되거나 취소되기를 기다림
    bool result = await Task.WhenAny(tcs.Task, Task.Delay(Timeout.Infinite, cts.Token)) == tcs.Task && tcs.Task.Result;

    if (!result)
    {
        Debug.LogWarning("저장 실패: 서버 응답이 60초 내에 도착하지 않았습니다.");

        // 트랜잭션 요청에 대한 리스폰스가 없어 게임 종료
    }
}
catch (OperationCanceledException)
{
    Debug.LogWarning("저장 실패: 서버 응답이 60초 내에 도착하지 않았습니다.");
    // 예외 시 게임 종료
}
finally
{
    cts.Dispose();
}

/// GetParm 관련 코드
  public TransactionValue GetTransactionUpdateValue() {
      return TransactionValue.SetUpdateV2(GetTableName(), GetInDate(), Backend.UserInDate, GetParam());
  }

 public override Param GetParam() {
     Param param = new Param();
 // ----------생략--------------     
     if (TrainingStatList != null && TrainingStatList.Count > 0)
         param.Add("TrainingStatList", TrainingStatList);

     if (LevelUpStatList != null && LevelUpStatList.Count > 0)
         param.Add("LevelUpStatList", LevelUpStatList);

     if (RankStatList != null && RankStatList.Count > 0)
         param.Add("RankStatList", RankStatList);

     if (HorseStatList != null && HorseStatList.Count > 0)
         param.Add("HorseStatList", HorseStatList);

     if (PagiStatList != null && PagiStatList.Count > 0)
         param.Add("PagiStatList", PagiStatList);

     param.Add("AttackAdsLevel", AttackAdsLevel.GetDecrypted());
     param.Add("HpAdsLevel", HpAdsLevel.GetDecrypted());
     param.Add("GoldAdsLevel", GoldAdsLevel.GetDecrypted());
     param.Add("ExpAdsLevel", ExpAdsLevel.GetDecrypted());

     Dictionary<int, float> GoodTemp = new Dictionary<int, float>();

     Dictionary<int, ObscuredFloat>.KeyCollection keys = GoodsDicts.Keys;

     foreach(int key in keys)
     {
         if(GoodTemp.ContainsKey(key) == true)
             GoodTemp[key] += GoodsDicts[key];
         else
             GoodTemp.Add(key, GoodsDicts[key]);
     }

     param.Add("GoodsDicts", GoodTemp);

     return param;
 }
좋아요 1

안녕하세요 개발자님,
관련 내용 상세 확인 시 트랜잭션 요청중에 Param에 들어있는 값들의 데이터가 삭제되면 발생하는 에러로 확인됩니다.
Param의 경우, Add 된 데이터 값에 대해 복사가 아닌 참조로 적용이 되기에
Param에 추가하였음에도 값이 변동되면 Param에 영향을 끼치게 됩니다.

추후 업데이트되는 SDK를 통해서는 Param 값이 복사 적용되어 동일한 문제 상황이 발생하지 않도록 개선될 예정으로,
동일 에러 발생을 막기 위해 Param에 들어가는 값을 깊은 복사를 통해 넣어 이용해 주시면 감사하겠습니다.

좋아요 1

안녕하세요.
해당 이슈 관련해 추가 질문드립니다.
모든 데이터를 트랜잭션으로 저장중인데,
혹시 해당 오류로 인해 일부 테이블만 저장되고 일부 테이블은 저장되지 않는 경우도 있을까요?
며칠전부터 특정 유저가 위와 같은 증상을 계속 겪는다고 문의를 해서
해당 유저의 데이터를 개별적으로 모니터링하고 있는데 이상한 부분이 있어서 문의드립니다.
해당 유저의 닉네임은 ‘’ 입니다.

안녕하세요 개발자님,
문의하신 내용과 관련해 추가 정보 확인이 필요하여 DM 드렸습니다.