Autour de Laravel

Question sur le verroullage des tables?

  • Avatar de kabeda
    Membre depuis :
    10/10/2017
    Messages :
    16

    Bonjour,
    Lors de la création d'un article, je dois lire de la table la valeur du dernier Order que je mets dans une variable dont j'incrémente la valeur puis je crée mon nouvel enregistrement.
    A savoir que Order n'a rien à voir le ID automatique.
    Ce que j'aimerais savoir c'est que, comme j'ai plusieurs utilisateurs qui interviennent sur mes enregistrements, est-ce qu'il y a un risque que si deux utilisateurs enregistrent deux articles différents, je puisse me retrouver avec la même valeur lue depuis la table?
    Si c'est le cas, est-ce qu'il y a un moyen avec laravel de mettre en différé une lecture tant que la table n'est pas libre? Une sorte de Lock.

    Merci,

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2569

    Bonjour,

    Il est toujours possible qu'une modification de la base se produise après la lecture d'une information. Une solution efficace consiste à utiliser des transactions complétées par un verrouillage.

  • Avatar de kabeda
    Membre depuis :
    10/10/2017
    Messages :
    16

    Bonjour,
    Merci @bestmomo,
    Pourrais-tu m'orienter sur un lien ou un tuto? J'avais compris que c'était une histoire de verrouillage (Lock). Mais comment faire avec Laravel?

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2569

    Salut,

    Il y a quelques articles sur le sujet comme celui-ci.

  • Avatar de kabeda
    Membre depuis :
    10/10/2017
    Messages :
    16

    Bonjour,
    Merci mais je ne trouve pas réponse à ma question concernant le verrouillage d'une table en lecture.

    Voilà ce que je cherche à faire

    $payload = $request->only(
    'titre', 'text', 'resume', 'visible', 'position', 'ordre',
    'image_text', 'image_visible', 'categorie_id',
    'publication_date', 'player_id', 'video_url', 'surtitre', 'commentable'
    );

    // JE CHERCHE A BLOQUER LA LECTURE DE LA TABLE DE FACON A CE QUE
    // LA VALEUR DE articles.ordernum NE SOIT PAS UTILISE
    // PAR UN AUTRE UTILISATEUR

    $ordernum = Article::select('order_num')->max('order_num')+1;
    $article = new Article($payload);
    $article->order_num = $ordernum;
    $article->save();

    // APRES LA SAUVEGARDE JE LIBERE LA TABLE

    Merci,

  • Avatar de kabeda
    Membre depuis :
    10/10/2017
    Messages :
    16

    Bonjour,
    Je suis en train de lire https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html

    Je vais essayer de l'implémenter sur ma routine de création.

    Je me propose de faire

    DB::raw('SET autocommit=0;');
    DB::raw('LOCK TABLES articles WRITE');
    $ordernum = Article::select('order_num')->max('order_num')+1;
    $article = new Article($payload);
    $article->order_num = $ordernum;
    $article->save();
    DB::raw('COMMIT; UNLOCK TABLES;');

    Qu'est ce que tu en penses? Y-a-til une autre méthode plus appropriée Laravel?

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2569

    Salut,

    Il n'y a pas de fonctionnalité particulière pour ça dans Laravel, par contre tu drvais inclure tout ça dans une transaction.

  • Avatar de kabeda
    Membre depuis :
    10/10/2017
    Messages :
    16

    Bonjour,
    Donc comme celà?

    $payload = $request->only(
    'titre', 'text', 'resume', 'visible', 'position', 'ordre',
    'image_text', 'image_visible', 'categorie_id',
    'publication_date', 'player_id', 'video_url', 'surtitre', 'commentable'
    );

    DB::transaction(function () use ($payload) {
    DB::raw('SET autocommit=0;');
    DB::raw('LOCK TABLES articles WRITE');
    $ordernum = Article::select('order_num')->max('order_num')+1;
    $article = new Article($payload);
    $article->order_num = $ordernum;
    $article->save();
    DB::raw('COMMIT; UNLOCK TABLES;');
    }, 5);

    Merci

Vous ne pouvez pas répondre à ce sujet.