Rails et transactionnel


#1

Bonjour à tous,

Le contexte est le suivant :

  • j’ai un model Person qui est associé en has_many à Pets et Cars
  • j’ai un formulaire unique permettant de saisir les données “Person”
    ainsi
    que les données associées “Pets” et “Cars”
  • dans mon controller pour l’update :
    person = Person.find(params[:id])
    pets = person.pets << Pet.new…
    cars = person.cars << Car.new…
    person.save

Le problème maintenant :
Lors du save, différents contrôle de validation sont effectués sur les
différents objets. Si pets renvoi une erreur, person n’est pas
sauvegardé
mais cars oui !

La question :
Y a-t-il moyen de faire un rollback général sur les transactions liées
au
save lorsqu’une erreur survient ?

D’avance merci

Sam


#2

Samuel DECHOMETS wrote the following on 15.03.2007 16:43 :

   person.save

Le problème maintenant :
Lors du save, différents contrôle de validation sont effectués sur les
différents objets. Si pets renvoi une erreur, person n’est pas
sauvegardé mais cars oui !

La question :
Y a-t-il moyen de faire un rollback général sur les transactions liées
au save lorsqu’une erreur survient ?

Person.transaction do
person = Person.find(params[:id])
pets = person.pets << Pet.new…
cars = person.cars << Car.new…
person.save
end


#3

Lionel B. wrote the following on 15.03.2007 17:14 :

Person.transaction do
person = Person.find(params[:id])
pets = person.pets << Pet.new…
cars = person.cars << Car.new…
person.save

oups, il faut faire person.save! (pour faire un rollback si ça se passe
mal).


#4

Mea culpa, j’ai mal retranscrit mon code, j’utilise bel et bien le save!
mais le rollback s’effectue seulement sur “person”, pas sur “cars”…

2007/3/15, Lionel B. removed_email_address@domain.invalid:


#5

Je suis aussi en train d’étudier les transactions pour des raisons de
perfs (d’après


ça devrait jouer), et, AMHA, le système de transaction de Rails se
faisant au niveau objet, quand tu écris “Person.transaction”, la
transaction ne sera valable que pour les modèles de type Person. Comme
dit, je peux me tromper, mais je le vois bien comme ça.

++

yk

Samuel DECHOMETS a écrit :


#6

J’ai essayé :

ActiveRecord::Base.connection.transaction do

Mais c pas mieux (qui ne tente rien n’a rien !).

Dans les logs j’ai bien un rollback, mais la requete d’insert de “Cars”
est
“entourée” d’un begin-commit, quand le rollback s’applique, l’insert de
“cars” a déjà été commité. Y’a pas moyen de désactiver le begin commit
automatique sur les requêtes de mise à jour ?

Sam

Le 15/03/07, Yann K. removed_email_address@domain.invalid a écrit :


#7

Yann K. wrote the following on 15.03.2007 17:43 :

Je suis aussi en train d’étudier les transactions pour des raisons de
perfs (d’après
http://www.antoniocangiano.com/articles/2007/02/10/top-10-ruby-on-rails-performance-tips
ça devrait jouer), et, AMHA, le système de transaction de Rails se
faisant au niveau objet, quand tu écris “Person.transaction”, la
transaction ne sera valable que pour les modèles de type Person.

Non, non, pour toutes les manipulations sur les objets utilisant la même
connexion à la base, donc par défaut tous les objects ActiveRecord::Base
de ton application. Une remarque néanmoins : je pense que si tu utilises
un SGBD qui ne supporte pas les transactions (MySQL avec MyISAM par
exemple), elles sont automatiquement désactivées et en plus
silencieusement, donc tout se passe en pratique comme si tu n’avais pas
de transaction.

Lionel


#8

Salut,

J’ai pas le temps de me replonger la-dedans en détail mais essaie ce
plugin: http://rubyforge.org/projects/arnesttransacts/
Il est possible que çà règle ton souci (sans garantie!).

Simon


#9

La boulette ! Effectivement, mes tables étaient en MyIsam. Je les ai
passées
en InnoDb et ça fonctionne…

Merci à tous

Sam

Le 15/03/07, Lionel B. removed_email_address@domain.invalid a écrit :


#10

Nicolas P. wrote the following on 20.03.2007 18:09 :

Salut Sam,

Juste pour info et pour ne pas être pris de court, les transactions
dans rails sont deprecated et seront supprimé en v2.0 :
http://dev.rubyonrails.org/changeset/6439?new_path=trunk

Euh, les transactions sur objet. Le jour où ils suppriment les
transactions totalement, je forke…


#11

Salut Sam,

Juste pour info et pour ne pas être pris de court, les transactions
dans rails sont deprecated et seront supprimé en v2.0 :
http://dev.rubyonrails.org/changeset/6439?new_path=trunk

à +
np

Le 16 mars 07 à 08:36, Samuel DECHOMETS a écrit :