Autour de Laravel

Question sur le verroullage des tables?

Avatar de kabeda
kabeda

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
bestmomo

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
kabeda

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
bestmomo

Salut,

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

Avatar de kabeda
kabeda

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
kabeda

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
bestmomo

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
kabeda

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.