Passer au contenu principal

Pourquoi les nouvelles tentatives d’achat créent des droits en double et comment les tester

Diagramme original du registre d'achat Persistium montrant une intention, un enregistrement durable et une décision d'admissibilité sûre de rejouer.

Comment modéliser l'intention d'achat, les résultats de l'engagement inconnu, les relevés et l'unicité des droits afin qu'un achat puisse être réévalué en toute sécurité sans accorder deux fois.

Une réessayer n'est pas une seconde décision d'achat

Un reçu peut arriver deux fois. Une demande réseau peut s'arrêter après l'état du serveur engagé mais avant que le client ait reçu la réponse. Un processus peut s'écraser après la réservation d'une transaction mais avant l'octroi de la monnaie. Au redémarrage, l'action la plus sûre peut être de réessayer le travail qui a été interrompu. Si le système traite chaque réessayer comme autorisation d'accorder, les droits dus sont une conséquence normale de la récupération.

La distinction utile est l'intention par rapport à la subvention. L'intention est la demande d'obtenir un produit spécifique sous une identité de transaction spécifique. La subvention est le résultat durable côté jeu: la propriété de droits, un delta de devises, un article d'inventaire, ou une période d'abonnement. La même intention peut être livrée, interrogée, rétriée ou retransmise à plusieurs reprises.

C'est un modèle d'ingénierie, pas une garantie spécifique à la plate-forme. Différents magasins, fournisseurs de paiement et backends de jeu exposent différents comportements de réception, d'accusé de réception et de remboursement. Ne présumez pas qu'un reçu prouve une subvention, ou qu'un accusé de réception prouve que le joueur a vu un article.

Donnez à chaque intention d'achat une clé stable

Une clé idempotency lie les tentatives répétées de livraison à une décision. Elle peut dériver d'un identifiant de transaction de plateforme de confiance lorsque cet identifiant est disponible et vérifié, ou elle peut être émise par un serveur avant le début d'un achat et liée plus tard à des informations de réception de confiance. La clé doit être stable entre les relevés.

Conservez suffisamment de contexte avec la clé pour rejeter les erreurs d'appariement : portée du joueur ou du compte, identité du produit, quantité prévue ou forme du droit, canal source, temps reçu, état de vérification, et un état tel que pendant, engagé, rejeté, ou besoin-révision. Gardez le matériel de réception sensible hors des journaux ordinaires. Si les charges utiles du fournisseur brut ont besoin d'une courte rétention pour un flux de récupération vérifié, protégez-les séparément et faites leur accès délibéré.

Le modèle de données a également besoin d'une limite unique. Pour un droit non-consommable, l'unicité peut être le compte plus l'ID du produit. Pour la monnaie, l'unicité est généralement l'entrée du grand livre ou la transaction de subvention plutôt que le solde courant. Pour les consommables, un identifiant de transaction fiable peut être unique même lorsque l'ID du produit se répète.

Modéliser le résultat de validation inconnu

Le résultat difficile n'est pas un succès propre ou un échec propre. Il est inconnu: le client ne sait pas si le serveur a commis la subvention. Un délai d'exécution, de réinitialisation de connexion, de redémarrage de processus ou de panne de service peut produire cet état. Le comportement du client sûr est de demander l'état de transaction ou de réessayer la même intention. Le comportement du serveur sûr est de rechercher cette intention et de retourner la décision durable plutôt que d'appliquer une autre mutation.

Un spinner disparaissant, un cache de réception local, ou un changement d'équilibre optimiste peut améliorer l'expérience, mais il ne peut pas décider si le compte possède un droit. L'autorité du serveur signifie que le serveur vérifie la transaction acceptée selon la limite de confiance du produit, engage l'enregistrement durable une fois, et retourne l'état courant lorsqu'il est demandé à nouveau.

Diagramme de séquence d'achat original montrant les tentatives répétées de livraison convergent sur un registre et une décision de versement.
Récupérer et recevoir une nouvelle fois la résolution contre la même intention d'achat durable plutôt que de créer de nouvelles subventions.

Par exemple: recevoir l'intention, valider des preuves d'achat fiables, créer ou charger l'enregistrement du registre durable, engager le droit ou la mutation de monnaie, marquer l'enregistrement accordé, reconnaître la livraison externe au besoin, puis retourner le résultat. Si le processus s'arrête entre deux étapes, un travailleur de récupération ou une requête de statut ultérieure peut reprendre à partir de l'enregistrement durable. La commande exacte dépend du fournisseur externe et de l'architecture du jeu, mais l'identité de subvention unique ne le fait pas.

Protéger les droits et les invariants monétaires

Une clé d'idempotency empêche le rejouage d'une seule intention; elle ne corrige pas automatiquement tous les effets secondaires. Définissez les invariants qu'une subvention doit conserver. Un droit non consommable apparaît au maximum une fois pour le compte et le produit. Une subvention en monnaie a une entrée du grand livre avec une clé de transaction, un delta connu, et un solde résultant qui correspond à la somme des entrées valides.

Faire le contrôle invariant partie de la même opération durable qui engage la subvention. Une lecture suivie d'un écrit ultérieur peut courir sous la livraison simultanée. Deux travailleurs peuvent à la fois observer --pas possédé et les deux subvention. Utilisez le stockage transactionnel, la sémantique de comparaison et-set, un chemin de mutation de compte sérialisé, ou un autre primitif de proximité explicite adapté au magasin de données. La propriété importante est que la décision et son marqueur ne peut pas être gagné indépendamment par deux tentatives.

Pour les jeux avec un runtime in-memory, distinguer le succès durable de la présentation. Le serveur peut mettre à jour l'équilibre visible d'un joueur après les commits d'entrée du grand livre durable, mais la mise à jour visible n'est pas la preuve. Sur reconnecter ou redémarrer, reconstruire l'état présenté à partir de l'enregistrement de compte durable.

Essais d'écrasement, de redémarrage et de redémarrage délibérément

Commencez par un scénario déterministe. Créez un compte, un produit, un équilibre de départ connu ou un ensemble de droits, et une clé de transaction stable. Exécutez le flux, puis injectez une défaillance après chaque limite nommée : après acceptation de la réception, après la création du grand livre, après mutation de droits, après marquage de statut, après reconnaissance externe, et après la préparation de la réponse.

Le résultat attendu devrait être précis. Un nouvel essai peut retourner -déjà accordé avec le résultat original, reprendre une opération en attente, rejeter une charge utile mal ajustée, ou tenir un dossier pour examen. Il ne devrait pas ajouter un deuxième élément d'inventaire, appliquer un second delta de monnaie, ou cacher l'état inconnu avec un succès fabriqué. Capturer la classification dans le résultat d'essai de sorte qu'un refacteur ultérieur ne peut pas transformer une cale intentionnelle en duplication accidentelle.

Utilisez le récépissé de récépissé dans le même scénario. Délivrez la transaction de confiance exacte deux fois, puis livrez-la après un redémarrage, puis livrez-la en même temps qu'un double client. Le registre et l'état du compte devraient être identiques à l'affaire de livraison unique.

Que les frontières restent honnêtes

Les tests ne peuvent prouver que les interactions que vous exécutez. Une réponse simulée du fournisseur peut valider votre machine d'état, mais il n'est pas prouvé que chaque bord fournisseur de production se comporte exactement de la même manière. Un test exécutable contre un bac à sable peut ajouter de la confiance pour cette intégration, mais a encore des conditions opérationnelles différentes d'un magasin en direct.

La limite de confiance doit également être claire. Un client ne doit pas soumettre un montant arbitraire, l'ID de produit, ou l'option de vérification et recevoir une subvention. Les entrées ne sont pas fiables jusqu'à ce que le serveur les valide contre la configuration pertinente et les preuves d'achat. Si la validation ne peut pas terminer, garder l'intention en attente ou la rejeter avec une catégorie récupérable.

La protection de la vie privée s'applique à cette discipline d'essai. Les installations doivent utiliser des données de transaction synthétiques. Les journaux doivent mentionner un identifiant de test sûr, non un reçu brut ou un nom de compte.

Liste de contrôle pratique

  • Séparer une intention d'achat stable de la subvention ultérieure côté jeu.
  • Utilisez une clé d'idempotency à travers les timeouts, les retraits, les redémarrages et la réédition des reçus.
  • Relier la clé du compte, du produit ou de la forme du droit, et du contexte source de confiance.
  • Définir des états durables tels que l'attente, l'engagement, le rejet et l'examen des besoins.
  • Appliquer l'unicité des droits et les invariants du grand livre de devises à l'intérieur de la même frontière commune que la subvention.
  • Injectez les échecs après chaque transition d'état, puis redémarrez et réessayez la même intention.
  • Tester séparément la livraison en double et les achats légitimes.
  • Signaler les résultats inconnus honnêtement; ne pas transformer un délai en succès inventé.
  • Gardez les appareils de réception et les registres d'essai synthétiques et expurgés.

Foire aux questions

Est-ce qu'un identifiant de reçu unique suffit pour l'idempotency?

Il peut s'agir d'un élément utile lorsque le serveur peut vérifier que l'identité du reçu est digne de confiance et qu'elle s'applique correctement. Il est important de conserver la décision de subvention, la politique d'inadéquation et l'état de récupération qui en résulte. Un système peut recevoir le même identifiant à plusieurs reprises, le recevoir en retard ou le recevoir avec une charge utile qui ne correspond pas au contexte du produit stocké.

Un client devrait-il réessayer automatiquement après un délai?

Habituellement, il doit reessayer la résolution de l'état en utilisant la même identité d'intention, avec un backoff limité et la rétroaction claire de l'utilisateur. S'il doit soumettre à nouveau des preuves d'achat externe dépend du fournisseur et de la conception de vérification. Le comportement dangereux est silencieusement créer une nouvelle demande d'achat ou appliquer une subvention locale parce que la réponse originale a été perdue.

En quoi les consommables diffèrent-ils des droits permanents?

Les produits consommables peuvent permettre l'achat du même produit à plusieurs reprises, de sorte que la limite d'unicité doit inclure une identité de transaction ou une séquence de grand livre plutôt qu'un seul ID de produit.

Que prétend Persistium ici ?

Persistium est en cours de développement. Cette note explique l'intégrité largement applicable et les modèles de conception de test; elle ne revendique pas un produit d'achat public, la certification de plate-forme, l'historique des incidents clients, ou un service hébergé.

Système connexeExplorer Persistium