2009-12-30 12 views
2

J'ai quelques méthodes qui devraient être exécutées seulement dans le cas où ma classe de conducteur DBI est actuellement dans une transaction pour assurer l'intégrité des données. Je cherche à écrire quelque chose comme ceci:Comment puis-je tester si l'état du pilote DBI est dans une transaction?

sub m{ 
    my ($self , $dbh) = @_ ; 
    unless($dbh->isInTransaction()){ 
    die "Use this only within a transaction\n" ; 
    } 
    etc ... 
} 

De la documentation pour begin_work, je comprends que begin_work mettra à AutoCommit au large pendant le temps de la transaction et le remettre à « sur » le commettre ou rollback, mais je me demande si tester la valeur de l'attribut AutoCommit est un moyen sûr de mettre en œuvre isInTransaction.

Merci pour votre aide.

J.

Répondre

7

Si vous activez AutoCommit et lancer des transactions avec $ dbh-> begin_work, vous pouvez tester pour voir si vous êtes dans une transaction:

if ($dbh->{BegunWork}) { 

Si vous désactivez AutoCommit, DBI ne vous aide pas beaucoup: vous ne pouvez vérifier les déclarations actifs reliés à la base de données poignée:

if ($dbh->{ActiveKids}) { 

Je ne l'ai jamais dû vérifier s'il y avait une transaction active - il me surprend, il n'y a pas de soutien. Vous devriez probablement suivre vous-même les transactions dans un wrapper sur DBI (ou injecter des méthodes dans DBI). Extension BegunWork pour être utile avec AutoCommit désactivé ressemble à un correctif DBI de base.

+0

Ce 'BegunWork' est exactement ce dont j'ai besoin (Oui j'utilise AutoCommit). Je ne peux pas le trouver dans le document DBI cependant. Est-ce une fonctionnalité non documentée? – jeje

+0

Oui, ce n'est pas documenté - c'est pourquoi j'ai été surpris qu'il n'y ait pas de support. Cela semble être une chose si simple à fournir. –

0

Est-ce votre base de données indépendante code? Si vous lisez attentivement la section sur AutoCommit car il existe des différences importantes entre les bases de données en fonction de la façon dont ils traitent les transactions. Mais si vous savez déjà que votre base de données traite les transactions de la façon dont vous avez besoin, alors AutoCommit devrait aller.

+0

C'est indépendant de la base de données oui, et je voudrais le garder comme ça :) – jeje

+0

J'ai utilisé ce mot un peu négligemment. Qu'est-ce que je voulais dire, savez-vous quel type de base de données votre code va fonctionner? – Dan

+0

Oui, postgresql. – jeje

1

Si vous écrivez votre propre classe wrapper, vous pouvez envelopper begin_work et les autres méthodes de transaction afin de pouvoir conserver votre propre état. Sinon, vous dépendez de fonctionnalités ou d'hypothèses non documentées qui peuvent changer, en particulier si vous devez passer à un autre pilote.