[RUBY] [Rails] J'ai essayé d'implémenter une transaction qui combine plusieurs processus DB

introduction

Je développais une application avec Rails et implémentais le processus de création de données pour plusieurs tables en même temps. Dans ce processus, j'ai appris qu'il existe un concept de transaction qui rend les deux processus absents lorsque l'un ou l'autre des processus échoue, donc j'écrirai sur la transaction et le contenu implémenté sous forme de mémorandum et de sortie.

Qu'est-ce que la transaction

Recherche de la définition du mot "transaction" [Traitement, manipulation, traitement, affaires, commerce, achat et vente, bulletin d'information, bulletin, minutes] Cela sort comme ça.

En informatique et programmation "Des choses indivisibles qui combinent plusieurs processus en un"

Il semble que cela puisse être défini comme.

Cet article est un résumé très facile à comprendre du concept de transaction, et je l'ai utilisé comme référence.

Qu'est-ce qu'une "transaction"? J'ai essayé d'en parler de manière super simple!

utilisation de la méthode de transaction

La syntaxe de base est comme ça


modèle.transaction do
  #Traitement d'accès aux tables
  #Traitement d'accès aux tables
end
  #Traitement lorsque le traitement de la transaction est réussi
rescue => e
  #Traitement lorsque le traitement de la transaction échoue

En guise de mise en garde, "utilisez une méthode qui déclenche une exception lorsque le traitement échoue".

Si une transaction échoue dans l'un des processus inclus, elle supposera que tous les processus de la transaction n'ont pas été exécutés, mais la condition pour ne pas le faire est "une exception s'est produite".

Mettons-le en œuvre.

la mise en oeuvre

L'application que nous développions cette fois avait une fonction de regroupement d'utilisateurs. Par conséquent, il est supposé que l'utilisateur qui a créé le groupe devient automatiquement l'utilisateur qui appartient au groupe lors de la création d'un nouveau groupe. Par conséquent, lors de la création d'un groupe, envisagez d'utiliser une transaction pour éviter un comportement inattendu.

La structure de la table est comme ça. スクリーンショット 2020-07-07 19.57.10.png

En même temps que la création de l'instance de la table groups, j'ai voulu créer une table group_users (table intermédiaire entre la table users et la table groups) avec l'id de l'utilisateur connecté comme colonne user_id.

  1. Créer une instance de table de groupes
  2. Créez une instance de table group_users

Si l'un de ces processus 1 et 2 échoue pour une raison quelconque, la transaction est utilisée dans l'action de création du contrôleur de groupes afin que les deux processus n'aient pas été traités.

groups_controller.rb


#Extrait de la partie action de création
#Courant variable_user contient une instance de l'utilisateur connecté

  def create
    @group = Group.new(group_params)

    #Appliquer la transaction(Créer un groupe et créer une table intermédiaire en même temps)
    # save!Et créer!Quand"!Veuillez noter que "" est joint!
    @group.transaction do
      @group.save!
      current_user.group_users.create!(group_id: @group.id, permission: true)
    end
    #Traitement lorsque la transaction est réussie
      flash[:success] = 'Créer un nouveau groupe'
      redirect_to @group
    rescue => e
    #Traitement lorsqu'une transaction échoue
      flash.now[:danger] = 'La création du groupe a échoué'
      render :new
  end

Notez que les deux processus de cette transaction sont marqués d'un "!" Et utilisez une méthode qui déclenche une exception lorsque la création de données de table échoue!

Si ce qui suit est implémenté sans utiliser de transaction, il est à craindre qu'un groupe non habité soit créé si la création de la table group_users échoue pour une raison quelconque.

groups_controller.rb



#Lorsque vous n'utilisez pas de transaction

def create
  @group = Group.new(group_params)

  if @group.save
    current_user.group_users.create(group_id: @group.id, permission: true)
    flash[:success] = 'Créer un nouveau groupe'
    redirect_to @group
  else
    flash.now[:danger] = 'La création du groupe a échoué'
    render :new: 
  end
end

finalement

Merci d'avoir lu l'article! J'ai réussi à le mettre en œuvre en enquêtant cette fois, mais honnêtement, je n'ai pas une compréhension approfondie des transactions. Si vous avez des erreurs ou de meilleures méthodes de description, n'hésitez pas à commenter. J'ai utilisé l'article suivant comme référence. Merci beaucoup.

Recommended Posts

[Rails] J'ai essayé d'implémenter une transaction qui combine plusieurs processus DB
J'ai essayé de créer une API Web qui se connecte à DB avec Quarkus
J'ai essayé d'implémenter un serveur en utilisant Netty
[Rails] J'ai essayé de créer une mini application avec FullCalendar
[Rails] J'ai essayé d'implémenter le traitement par lots avec la tâche Rake
J'ai essayé d'implémenter une application web pleine de bugs avec Kotlin
J'ai essayé d'implémenter la fonction de prévisualisation d'image avec Rails / jQuery
J'ai essayé de créer une application simple en utilisant Dockder + Rails Scaffold
J'ai essayé de créer une fonction de groupe (babillard) avec Rails
J'ai essayé d'implémenter le modèle Iterator
Comment mettre en œuvre un diaporama en utilisant Slick in Rails (un par un et plusieurs par un)
Mode API Rails J'ai essayé d'implémenter la fonction de recherche multiple par mot-clé à l'aide de tableaux et d'un traitement itératif.
J'ai essayé de mettre facilement CentOS-7 dans un PC dont je n'ai plus besoin
J'ai essayé d'implémenter des relations polymorphes à Nogizaka.
[Première construction d'environnement] J'ai essayé de créer un environnement Rails6 + MySQL8.0 + Docker sur Windows 10.
J'ai essayé d'implémenter une fonction équivalente à Felica Lite avec HCE-F d'Android
[Rails] J'ai essayé de faire passer la version de Rails de 5.0 à 5.2
J'ai essayé d'organiser la session en Rails
java j'ai essayé de casser un simple bloc
J'ai essayé de développer un outil de gestion des effectifs
J'ai essayé de développer un site Web pour étudier DUO3.0.
J'ai essayé de créer une application de clonage LINE
Comment implémenter une fonctionnalité similaire dans Rails
J'ai essayé de développer un site Web pour enregistrer les dépenses.
J'ai essayé de casser le bloc avec java (1)
J'ai essayé d'utiliser Wercker pour créer et publier une image Docker qui lance GlassFish 5
J'ai essayé de créer une fonction de message de l'extension Rails Tutorial (Partie 1): Créer un modèle
Je souhaite utiliser PowerMock dans une classe qui combine des tests paramétrés et des tests ordinaires
Une histoire à laquelle j'étais accro lors de l'obtention d'une clé qui a été automatiquement essayée sur MyBatis
J'ai essayé d'implémenter le téléchargement de fichiers avec Spring MVC
Comment implémenter une fonctionnalité intéressante dans Ajax avec Rails
J'ai essayé d'implémenter TCP / IP + BIO avec JAVA
J'ai essayé d'implémenter la notification push Firebase en Java
J'ai essayé de développer un site Web de partage de boutique de ramen.
Je veux utiliser une petite icône dans Rails
J'ai essayé de créer une compétence Clova en Java
J'ai essayé de créer une fonction de connexion avec Java
Je souhaite définir une fonction dans la console Rails
J'ai essayé d'implémenter Sterling Sort avec Java Collector
Rails6 J'ai essayé d'introduire Docker dans une application existante
[Java] J'ai essayé de mettre en œuvre la recherche de produits de l'API Yahoo
J'ai essayé d'implémenter la méthode de division mutuelle d'Eugrid en Java
[Rails 6.0, Docker] J'ai essayé de résumer la construction de l'environnement Docker et les commandes nécessaires pour créer un portfolio
[Java] J'ai essayé de créer un jeu Janken que les débutants peuvent exécuter sur la console
J'ai essayé de créer une fonction de message pour l'extension Rails Tutorial (Partie 2): Créer un écran à afficher
J'ai essayé d'implémenter la fonction similaire par communication asynchrone
J'ai essayé de créer un environnement de développement java8 avec Chocolatey
J'ai essayé d'ajouter une ligne de séparation à TabLayout sur Android
J'ai essayé de moderniser une application Java EE avec OpenShift.
Je souhaite implémenter une fonction d'édition des informations produit ~ part1 ~