[RUBY] Lock_version peut être utilisé pour les tables qui ont tendance à accéder et à modifier le même enregistrement en même temps

introduction

J'ai lu le Rails Guide et j'étais curieux, alors je l'ai touché. Ce mémo.

Lorsque M. A et M. B éditent le même dossier dans la demande, si M. A accède au même dossier exactement au même moment, M. A met à jour le dossier et ensuite M. B met à jour, M. B édite le contenu de M. A. Il sera écrasé sans confirmation. S'il s'agit d'une mise à jour avec le même attribut, et s'il s'agit d'un autre attribut, l'édition sera rembobinée, ce qui n'est pas une bonne situation.

Active Record fournit lock_version pour ce problème. lock_version ajoute une colonne à la table qui agit comme un compte d'historique d'édition pour cette instance, et en référençant sa valeur Si vous utilisez lock_version, vous pouvez générer une erreur dans les cas ci-dessus.

comment utiliser

Pour l'utiliser, créez une colonne appelée lock_version dans la table.

t.integer :lock_version, default: 0

Contrôle de fonctionnement

p1 = Memo.find(1)
p2 = Memo.find(1)
# => #<Memo id: 1, text: "hello", lock_version: 0>

Bien sûr, lock_version vaut 0 quand il est toujours appelé Puis mettez à jour p1.

p1.update(text:'good bye')
# => #<Memo id: 1, text: "good bye", lock_version: 1>

SQL


   (0.3ms)  BEGIN
  Memo Update (13.4ms)  UPDATE `memos` SET `text` = 'good bye', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
   (3.9ms)  COMMIT

look_version a été réécrit à 1. Vous pouvez également voir que la condition SQL pour la mise à jour a lock_version = 0. Ensuite, mettons à jour p2. La lock_version de l'instance p2 reste 0 car elle n'a pas été rechargée.

p2.update(text:'say hello')
# => ActiveRecord::StaleObjectError (Attempted to update a stale object: Memo.)

SQL


   (0.7ms)  BEGIN
  Memo Update (1.0ms)  UPDATE `memos` SET `text` = 'say hello', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
   (2.4ms)  ROLLBACK

Vous obtenez une erreur. Je ne pense pas que SQL lui-même sera généré même si une erreur est exécutée, il semble donc qu'une erreur soit renvoyée avec le déclencheur indiquant qu'aucune ligne n'affecte les rails. Je ne lirai pas la source cette fois, donc si vous la lisez, partagez-la!

Contrôle de fonctionnement (Web)

Comme pour RailsApi, mettons lock_version comme paramètre caché dans le formulaire. Sans cela, le backend ne pourra pas comparer lock_version et ne générera pas d'erreur.

<input type="hidden" value="2" name="memo[lock_version]" id="memo_lock_version">

J'ai ajouté ce qui précède, ouvert deux onglets pour modifier le même enregistrement et mis à jour chacun, et celui qui a mis à jour plus tard a obtenu une erreur en toute sécurité. スクリーンショット 2020-07-26 11.22.12.png

Après cela, traitons l'erreur comme décrit dans Rails Api. Il existe différentes manières de gérer cela.

――Si deux personnes ont modifié des attributs différents, mettez-les à jour dans l'ordre et lorsqu'elles modifient le même attribut, affichez-le à l'écran et confirmez avec l'utilisateur.

Et. Je me demande si cette zone dépend de la façon dont les données sont utilisées sur l'application.

finalement

Je ne l'ai pas utilisé dans la pratique, donc je serais heureux si vous pouviez partager quelque chose comme "Je fais ça chez moi!"!

Article de référence

Rails Guide What is Optimistic Locking

Recommended Posts

Lock_version peut être utilisé pour les tables qui ont tendance à accéder et à modifier le même enregistrement en même temps
Méthode de mise en œuvre consistant à lier plusieurs images à un article et à publier en même temps
Outils et commandes pouvant être utiles pour le dépannage Java
Compétences de puissance qui peuvent être utilisées rapidement à tout moment - Réflexion
[Spring Boot] Publiez des fichiers et d'autres données en même temps [Axios]
Liste de réglages de Glassfish que je souhaite conserver pour le moment
Dessinez un graphique à barres et un graphique linéaire en même temps avec MPAndroidChart
Essayez Alfresco 6.0 sur Windows (Docker sera introduit en même temps)
Idéal et réalité que j'ai ressenti lorsque j'ai utilisé Optional pour la première fois ~ Implémentation du cache à l'aide de Map ~
[Affichage message ERREUR] Version simple utilisable à tout moment avec le gabarit partiel des rails