2010-11-25 19 views
1

J'ai une application MVC asp.net qui fonctionne pendant environ une semaine alors aujourd'hui a commencé à obtenir cette erreur.Je reçois la requête "PROMOTE TRANSACTION a échoué parce qu'il n'y a pas de transaction locale active" dans un System.Transaction.TransactionScope

Exécution sur .net 4.0, Win 2K8 R2 en conversation avec SQL Server 2K8 sur Win 2K8 R2.

Tous les serveurs sont équipés de MS DTC. Je fais une simple adhésion aspnet créer puis créer des données supplémentaires dans ma propre table d'utilisateur, à l'intérieur de la portée.

On dirait qu'une fois qu'une personne a rencontré l'erreur, tout le monde l'obtient et tente ensuite de créer un compte. D'autres fonctions de la base de données fonctionnent.

Voici la trace de la pile:

System.Transactions.TransactionAbortedException: The transaction has aborted. ---> System.Transactions.TransactionPromotionException: Failure while attempting to promote transaction. ---> System.Data.SqlClient.SqlException: The PROMOTE TRANSACTION request failed because there is no local transaction active. 
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 
    ... 
    at System.Data.SqlClient.SqlConnection.Open() 
    at Elmah.SqlErrorLog.Log(Error error) in c:\builds\ELMAH\src\Elmah\SqlErrorLog.cs:line 158 
    at KeyesTechnology.DemandLaunch.BusinessEntities.LoginAccount.CreateAccount() in c:\Products\DemandLaunch\Staging\KeyesTechnology\DemandLaunch\BusinessEntities \LoginAccount.cs:line 141 
    at www.ViewModels.CreateAccountViewModel.Process() in c:\Products\DemandLaunch\Staging\mvc\www\ViewModels\CreateAccountViewModel.cs:line 89 
    at www.Controllers.AccountController.Create(CreateAccountViewModel model, String returnUrl) in c:\Products\DemandLaunch\Staging\mvc\www\Controllers\AccountController.cs:line 85 
    at lambda_method(Closure , ControllerBase , Object[]) 

code:

using (System.Transactions.TransactionScope scope = new System.Transactions.TransactionScope()) 
{ 
    try 
    { 
    //Create ASP.NET Membership User 
    if (success) 
    { 
     //Create Domain Specific User Object 
     // Forms Authenication call 
    } 
    else 
    { 
     throw Exception(); 
    } 
    //Send Welcome Email 
    //Subscribe to Email List 

    scope.Complete(); 
    } 
    catch(Exception exc) 
    { 
    Elmah.Error error = new Elmah.Error(exc, HttpContext.Current); 
    Elmah.ErrorLog log = Elmah.ErrorLog.GetDefault(HttpContext.Current); 
    log.Log(error); //Error throws on this line 

    result = false; 
    } 
} 

J'ai compris que j'ai la dernière capture écrit au ELMAH qui est basé SQL
et il est après la portée complète donc ça ne marchera jamais. J'ai corrigé ce bug mais
il ne me dit pas pourquoi l'erreur se produit.
Pour tester j'ai jeté des exceptions juste avant et après le scope.Complete() instruction
J'ai fait une erreur intentionnelle immédiatement avant le scope.Complete(). Je n'obtiens pas d'erreur dans la page et aucune erreur ELMAH n'est enregistrée.
J'ai fait une erreur intentionnelle immédiatement après le scope.Complete(). Je reçois la portée est déjà terminée erreur dans la capture finale alors.
Je n'étais pas capable de comprendre ce qui ferait que le PROMOTE tente de se produire et pourquoi cela arriverait s'il l'était.
Le site s'est bien déroulé pendant 10 jours, puis nous avons cette erreur et tout le monde l'obtient par la suite pour essayer de créer un compte. Bien que d'autres parties de la base de données fonctionnent correctement. Juste cette fonction est foiré jusqu'à ce que nous redémarrons le SQL Server.

+0

C'est un mur de texte assez méchant. Vous pourriez obtenir plus de réponse si vous réduisez cela un peu. Aussi, avez-vous une transaction active lorsque vous faites cela? Peut-être que vous devriez ajouter du code à votre message. –

Répondre

3

Essayez de faire cela pour votre appel d'enregistrement:

using(TransactionScope scope 
    = new TransactionScope(TransactionScopeOption.Suppress)) 
{ 
    log.Log(error); //Error throws on this line 
} 

Je pense que l'appel de l'exploitation forestière tente de promouvoir une transaction distribuée (lorsque vous essayez de frapper votre enregistreur d'erreur). Ce code supprimera l'appel de journalisation de la transaction. J'ai eu le même problème pour un enregistreur lors d'un travail distribué. J'obtiendrais une erreur, j'échouerais puis je ferais un journal, ce qui ferait sortir la portée et tout annuler.