I am receiving "PROMOTE TRANSACTION request failed because there is no local transaction active" in a System.Transaction.TransactionScope
I have an asp.net MVC app thats running for about a week then today started to get this error.
Running on .net 4.0, Win 2K8 R2 talking to SQL Server 2K8 on Win 2K8 R2.
All servers have MS DTC running on them.
I am doing a simple aspnet membership create then creating additional data in my own user table, inside the scope.
Seems like once one person hits the error everyone gets it that tries to create an account after that. Other functions of the database are working.
Here is the stack trace:
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;
}
}
I have figured out that I have the last catch writing to the ELMAH which is SQL 开发者_JAVA技巧based
and it is after the scope complete so it will never work. I have fixed that bug but it doesn't tell me why the error is happening. To test I threw exceptions right before and after the scope.Complete() statement I made an intentional error immediately before the scope.Complete(). I get no error in page and no ELMAH error logged. I made an intentional error immediately after the scope.Complete(). I get scope is already completed error in the final catch then. I was not able figure out what would make the PROMOTE attempt to happen and why it would happen were it is. The site ran fine for 10 days then we get this error and everyone gets it afterwards that tries to create an account. Although other parts of the database are working fine. Just this function is messed up until we reboot the SQL Server.Try doing this for your logging call:
using(TransactionScope scope
= new TransactionScope(TransactionScopeOption.Suppress))
{
log.Log(error); //Error throws on this line
}
I think your logging call is trying to promote to a distributed transaction (when you try to hit your error logger). This code will take the logging call out of the transaction. I had the same problem for a logger when doing distributed work. I would get an error, fail and then log, which then would exit the scope and roll back everything.
精彩评论