Maison  >  Article  >  base de données  >  Comment Redis implémente les transactions distribuées

Comment Redis implémente les transactions distribuées

步履不停
步履不停original
2019-06-22 13:54:146794parcourir

Comment Redis implémente les transactions distribuées

Description du problème :

Une plateforme de commerce électronique lance un nouveau téléphone mobile. Chaque personne est limitée à l'achat de 2 unités, et on s'attend à ce qu'il y ait une concurrence de 10 W. Dans ce cas, si l'inventaire est déduit, il est garanti de ne pas être survendu

Solution 1

Utilisez le mécanisme de verrouillage de la base de données pour enregistrer le verrouillage, puis utilisez

SELECT * from goods where ID =1 for update;
UPDATE goods set stock = stock - 1;

Utilisez un verrouillage exclusif pour convertir le fonctionnement parallèle en fonctionnement en série, mais les performances et l'expérience utilisateur de cette solution sont médiocres

Solution 2

Utilisez redis pour implémenter des verrous distribués.

Utilisez la commande setnx (lorsque la clé n'existe pas, créez et définissez la valeur et renvoyez 1, lorsque la clé existe, elle renverra 0) pour obtenir le verrou. Dans la logique métier, nous pouvons opérer via un tel schéma

Jedis client = jedisPool.getResource();
        while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){
            Thread.sleep(10000);
        }
        //coding here 
       client.del("lock")

Schéma 2 avancé

Considérant le problème de blocage, c'est-à-dire qu'une fois que le prêt à l'emploi A a acquis le verrou, il tombe en panne, ce qui empêche le verrou d'être libéré. ​​Nous pouvons utiliser get La commande obtient l'horodatage du verrou, l'utilise pour déterminer le délai d'attente et le libère

    Long TIMEOUT_SECOUND = 120000L;
        Jedis client = jedisPool.getResource();
        while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){
            Long lockTime = Long.valueOf(client.get("lock"));
            if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) {
                client.del("lock");
            }
            Thread.sleep(10000);
        }
        ...........................
        ...........................
        client.del("lock")

L'option 2 se renforce

Dans l'algorithme de l'option 2, afin de garantir que dans les situations sans délai d'attente, le verrou ne peut être libéré que par Pour libérer le fil verrouillé, vous pouvez épeler le code de fonctionnalité du fil

    Long TIMEOUT_SECOUND = 120000L;
        String featureCode = "machine01";
        Jedis client = jedisPool.getResource();
        while(client.setnx("lock",featureCode+":"+String.valueOf(System.currentTimeMillis())) == 0){
            Long lockTime = Long.valueOf(client.get("lock").substring(9));
            if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) {
                client.del("lock");
            }
            Thread.sleep(10000);
        }
        ...........................
        ...........................
        if (featureCode.equals(client.get("lock").substring(0, 8))) {
            client.del("lock");
        }

dans l'horodatage de la valeur. Pour plus d'articles techniques liés à Redis, veuillez visiter la colonne Tutoriel Redis pour l'apprentissage !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn