Mysql
 sql >> Base de données >  >> RDS >> Mysql

Pourquoi Rails ignore-t-il un Rollback dans une transaction (pseudo)imbriquée ?

En fait, c'est exactement comme ça que Transactions imbriquées a été conçu pour. Je cite des documents oracle :

Ainsi, une transaction enfant dans une transaction imbriquée normale n'a pas son mot à dire sur la façon dont lui ou les autres enfants ou parents (transaction plus importante ) pourrait se comporter, autrement qu'en modifiant des données mutuelles ou en échouant pour une exception.

Mais vous pouvez lui accorder (transaction enfant ) une chance de vote très limitée sur son destin en utilisant la sub-transaction fonctionnalité comme indiqué dans rails docs en passant requires_new: true

User.transaction do
  User.create(username: 'Kotori')
  User.transaction(requires_new: true) do
    User.create(username: 'Nemu')
    raise ActiveRecord::Rollback
  end
end

Ce qui, comme le disent les docs :ne crée que 'Kotori'. puisque le puissant enfant 'Nemu' a choisi de mourir en silence.

Plus de détails sur les règles de transaction imbriquées (documentation oracle )

Mise à jour :

Pour mieux comprendre pourquoi rails nested transactions fonctionne de cette façon, vous devez en savoir un peu plus sur le fonctionnement des transactions imbriquées au niveau de la base de données, je cite de docs API rails :

Ok, alors la documentation décrit le comportement d'une nested transaction dans les deux cas mentionnés comme suit :

Dans le cas d'un appel imbriqué, #transaction se comportera comme suit :

  • Le bloc sera exécuté sans rien faire. Toutes les instructions de base de données qui se produisent dans le bloc sont effectivement ajoutées à la transaction de base de données déjà ouverte.

  • Cependant, si :requires_new est défini, le bloc sera enveloppé dans un point de sauvegarde de la base de données agissant comme une sous-transaction.

J'imagine attention, imagine seulement que :

option(1) (sans requirements_new) est là au cas où vous auriez utilisé un SGBD qui prend entièrement en charge les nested transactions ou vous êtes satisfait du "faux" comportement de nested_attributes

tandis que option(2) est de supporter le savepoint solution de contournement si vous ne le faites pas.