Skip to content
This repository has been archived by the owner on Apr 1, 2024. It is now read-only.

同時にDBにアクセスした新規ユーザに対して、重複しないように、DBに新規IDを登録したい( query.FindAsync中のDBでの処理に関する質問) #1340

Open
undgro03 opened this issue Dec 24, 2022 · 3 comments

Comments

@undgro03
Copy link

undgro03 commented Dec 24, 2022

現在、Unityでランキング機能付きのゲームを開発しています。
ランキング機能の実装にあたって、ニフクラをサーバーとして用いています。

実装方法として、DBの中で"userId"というプレイヤーに固有の値を、新規プレイヤーに1から順に割りあてていく方式を考えています。
このuserIdが重複しないように新規ユーザIDを生成・管理したいと考えており、下記コードによる実装をしているのですが、この際、query.FindAsyncの処理に関して疑問があります。

2人の新規プレイヤーが、同時にFindAsyncを行った場合に、サーバー側の処理として、
①1人のFindAsync の処理が終わったのち、もう1人のFindAsyncの処理が開始される
②2人で並列処理が行われる
のどちら(またはそれ以外)なのでしょうか?もし、②の場合、重複しないように管理するためにはどのように設計すればよいのでしょうか?

下記コードでは、次のような意図で処理を行っています。
1.ニフクラ上にUserIdManagerというクラスを作り、ユーザーID数を管理するため"userId"というフィールドを持たせます。
2.query.FindAsync((List objList, NCMBException e) でDBにアクセスし、"userId"の最新の値を取得します
3.ローカル変数のuserIdにDB上の"userId"に1を足した値を代入し、この値でDB上の"userId"を上書きします。
4.セーブデータの領域の、自分のIDを管理する変数(この場合はtestId)にuserIdを格納します

今回の質問としては、2人が同時アクセスした場合に、同じuserIdの値が取得されてしまう可能性があるのかどうかを知りたいです。
よろしくお願いします。

ニフクラ

using NCMB;
using System.Collections.Generic;
using UnityEngine;

namespace NCMB
{
    public class UserIdManager
    {
        public void GetUserId()
        {
            int userId;
            NCMBQuery<NCMBObject> query = new NCMBQuery<NCMBObject>("UserIdManager");
            query.FindAsync((List<NCMBObject> objList, NCMBException e) => {
            if (e == null) {
                if( objList.Count == 0 ) //userIdが1つも登録されていない場合の処理
                {
                    NCMBObject obj = new NCMBObject("UserIdManager");
                    obj["userId"] = 1;
                    obj.SaveAsync();
                    userId = System.Convert.ToInt32(obj["userId"]);
                }
                else //userIdが登録されている場合の処理
                {
                    userId = System.Convert.ToInt32(objList[0]["userId"]) + 1;
                    objList[0]["userId"] = userId;
                    objList[0].SaveAsync();
                }
                PlayerPrefs.SetString("testId", userId.ToString("D8"));
            }
            });
        }
    }
}
@undgro03 undgro03 changed the title ユーザIDが重複しないよう、DBに新規IDを登録する方法について。 query.FindAsync中のDBでの処理に関する質問 同時にDBにアクセスした新規ユーザに対して、重複しないように、DBに新規IDを登録したい( query.FindAsync中のDBでの処理に関する質問) Dec 24, 2022
@goofmint
Copy link

ネットワークで多人数が同時アクセスする前提なので、重複しない数字を割り当てる(いわばロックするような仕組み)のは無理かと思います。NCMB自体ではそういった動作の保証はしていませんので、同時に取得すれば重複した数値が割り当てられます。

@undgro03
Copy link
Author

ご回答どうもありがとうございます。
そうなんですね。となると、ユーザー重複しないようにするには、GUID値などを割り当てて、最初から重複の可能性を限りなく方法を採用したほうが良いのかもしれないですね。

@goofmint
Copy link

GUIDを割り当てるのであれば、objectIdを使ってもらう方が良いかなと。objectIdはユニークです。

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants