web-dev-qa-db-fra.com

Erreur "L'opération n'est pas valide pour l'état de la transaction" et étendue de la transaction

Je reçois le message d'erreur suivant lorsque j'essaie d'appeler une procédure stockée contenant une instruction SELECT:

L'opération n'est pas valide pour l'état de la transaction

Voici la structure de mes appels:

public void MyAddUpdateMethod()
{

    using (TransactionScope Scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        using(SQLServer Sql = new SQLServer(this.m_connstring))
        {
            //do my first add update statement

            //do my call to the select statement sp
            bool DoesRecordExist = this.SelectStatementCall(id)
        }
    }
}

public bool SelectStatementCall(System.Guid id)
{
    using(SQLServer Sql = new SQLServer(this.m_connstring)) //breaks on this line
    {
        //create parameters
        //
    }
}

Le problème est-il que je crée une autre connexion à la même base de données dans la transaction?

50
Michael Kniskern

Après quelques recherches, il semble que je ne puisse pas ouvrir deux connexions à la même base de données avec le bloc TransactionScope. Je devais modifier mon code pour ressembler à ceci:

public void MyAddUpdateMethod()
{
    using (TransactionScope Scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        using(SQLServer Sql = new SQLServer(this.m_connstring))
        {
            //do my first add update statement            
        }

        //removed the method call from the first sql server using statement
        bool DoesRecordExist = this.SelectStatementCall(id)
    }
}

public bool SelectStatementCall(System.Guid id)
{
    using(SQLServer Sql = new SQLServer(this.m_connstring))
    {
        //create parameters
    }
}
47
Michael Kniskern

J'ai également rencontré le même problème, j'ai changé le délai de transaction de 15 minutes et cela fonctionne. J'espère que ça aide.

TransactionOptions options = new TransactionOptions();
options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
options.Timeout = new TimeSpan(0, 15, 0);
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required,options))
{
    sp1();
    sp2();
    ...

}
8
Sharique

Lorsque j'ai rencontré cette exception, il y avait un "Expiration du délai de transaction" InnerException. Comme c'était pendant une session de débogage, quand j'ai arrêté mon code pendant un certain temps dans TransactionScope, j'ai choisi d'ignorer ce problème.

Lorsque cette exception spécifique avec un délai d'expiration apparaît dans le code déployé, je pense que la section suivante de votre fichier .config vous aidera:

<system.transactions> 
        <machineSettings maxTimeout="00:05:00" /> 
</system.transactions>
7
R. Schreurs

J'ai rencontré cette erreur lorsque ma transaction est imbriquée dans une autre. Est-il possible que la procédure stockée déclare sa propre transaction ou que la fonction appelante en déclare une?

2
Wyatt

Pour moi, cette erreur est survenue lorsque j'essayais d'annuler un bloc de transaction après avoir rencontré une exception, à l'intérieur d'un autre bloc de transaction.

Tout ce que je devais faire pour résoudre ce problème était de supprimer mon bloc de transaction interne.

Lorsque vous utilisez des transactions imbriquées, les choses peuvent devenir compliquées, il vaut mieux éviter cela et restructurer simplement votre code.

0
Vishav Premlall