9
votes

Transaction dans la transaction

Je veux savoir si Ouvrir une transaction à l'intérieur d'une autre est sûre et encouragé?

J'ai une méthode: xxx

et une méthode qui appelle le premier, à l'intérieur d'une transaction: xxx

Si je reçois et exceptions sur la méthode FOO, toutes les opérations seront annulées? Et tout le reste va bien fonctionner? merci !!


1 commentaires

Les transactions imbriquées (par exemple, l'autonomie de l'oracle) sont qualifiées comme un anti-motif de côté à partir de deux cas: l'audit (la tentative est donc auditée même si l'instruction roule en arrière) et la journalisation des erreurs (pour capturer où / lorsque des défaillances existent). Tous les autres cas doivent utiliser les points de sauvegarde. Heck, la portée de la transaction n'appartient pas à des fonctions ou de procédures; Il devrait être la responsabilité de l'appelant ultime de s'engager ou de rentabiliser.


3 Réponses :


0
votes

Vous ne pouvez pas, PostgreSQL ne prend pas en charge les soustransactions. Vous voudrez peut-être utiliser des points de sauvegarde, mais c'est autre chose.


3 commentaires

d'accord. Mais j'exécute le code ci-dessus et Sqlalchemy me permet de le faire. Que se passe-t-il derrière le rideau?


Je n'ai aucune expérience avec Sqlalchemy qu'est-ce qui tellement, je ne peux jamais vous aider là-bas. Mais je sais que PostgreSQL ne peut pas faire de sous-fransactions, Oracle est l'une des rares bases de données pouvant faire ce truc. Voir le manuel SQLALCHEMY.ORG/DOCS/Session.html#Maning --Transactions Comment Sqlalchemy effectue des transactions et des points de sauvegarde. Et test, test, test! Ne faites pas confiance à votre ormission quand il semble que cela vous permet de faire des choses que votre base de données ne peut pas faire ...


Mise à jour de lien: docs.sqlalchemy.org/en/rel_1_0/orm / ...



19
votes

Il y a deux façons de nier des transactions dans Sqlalchemy. L'une est des transactions virtuelles, où Sqlalchemy tient une trace du nombre de bons de départ que vous avez émis et publie le contrainte que lorsque la transaction la plus externe s'engage. La restauration est toutefois émise immédiatement. Parce que la transaction est virtuelle - c'est-à-dire la base de données ne sait rien de la nidification, vous ne pouvez rien faire avec cette session après la restauration jusqu'à ce que vous rentriez également toutes les transactions extérieures. Pour autoriser l'utilisation des transactions virtuelles Ajouter Sous -Ransactions = true code> argument sur le commencements () code> appel. Cette fonctionnalité existe pour vous permettre d'utiliser la commande de transaction à l'intérieur des fonctions pouvant s'appeler mutuellement sans tenir la piste si vous êtes dans une transaction ou non. Pour ce faire, configurez la session avec autocommit = true code> et émettez toujours un session.begin (soustransactions = true) code> dans une fonction transactionnelle.

L'autre sens Pour nier les transactions consiste à utiliser de vraies transactions imbriquées. Ils sont mis en œuvre avec des points de sauvegarde. Si vous retournez une transaction imbriquée, toutes les modifications apportées à cette transaction sont renvoyées, mais la transaction extérieure reste utilisable et que toute modification apportée par la transaction extérieure est toujours là. Utiliser une émission de transaction imbriquée session.begin (nichée = true) code> ou juste session.begin_neté () code>. Les transactions imbriquées ne sont pas prises en charge pour toutes les bases de données. Fonction de configuration de la bibliothèque SQLALCHEMY'S Test Suite sqlalchemy.test.requires.savepoints code> dit ceci sur le support: P>

    emits_warning_on('mssql', 'Savepoint support in mssql is experimental and may lead to data loss.'),
    no_support('access', 'not supported by database'),
    no_support('sqlite', 'not supported by database'),
    no_support('sybase', 'FIXME: guessing, needs confirmation'),
    exclude('mysql', '<', (5, 0, 3), 'not supported by database')


0 commentaires

0
votes

sur les transactions imbriquées PostgreSQL fonctionnent parfaitement.

Eh bien, vous n'allez pas avoir une erreur (juste un avertissement), c'est vrai. Mais vous ne pouvez pas commettre la transaction interne et la restauration de la transaction externe, la transaction extérieure annulera également la transaction interne.

commence;

Insérer dans les valeurs X (FOO) ('John');

commencer; - AVERTISSEMENT!

Insérer dans les valeurs Y (bar) ('Jane');

commettre; - commit une transaction interne

Rollback; - retournera les deux insertions, pas seulement le premier, celui du tableau "x"

À ma connaissance, Oracle est l'un des rares qui a cette option.


1 commentaires

Non imbriquées des transactions PostgreSQL. Sqlalchemy transactions nichées. La transaction interne entraîne une paire de sauvegarde de sauvegarde et de sauvegarde sur la valeur de sauvegarde. Cela entraîne un comportement que l'on pourrait s'attendre à des transactions imbriquées. Il est en fait mis en œuvre avec des points de sauvegarde sur le backend Oracle. J'ai clarifié la réponse en conséquence.