我在System.Transaction.TransactionScope中收到“PROMOTE TRANSACTION请求失败,因为没有本地事务处于活动状态”

时间:2010-11-25 15:04:15

标签: c# sql-server transactions ado.net

我有一个运行了大约一个星期的asp.net MVC应用程序,然后今天开始出现此错误。

在.net 4.0上运行,Win 2K8 R2与Win 2K8 R2上的SQL Server 2K8通信。

所有服务器都运行MS DTC。

我正在创建一个简单的aspnet成员资格,然后在我自己的用户表中,在范围内创建其他数据。

似乎一旦一个人遇到错误,每个人都会尝试在此之后创建一个帐户。数据库的其他功能正在发挥作用。

这是堆栈跟踪:

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[] )  

代码:

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;
  }
}

我已经发现我有最后一个写入ELMAH的文件,这是基于SQL的 它是在范围完成后,它将永远不会工作。我已经修复了这个bug但是 它没有告诉我为什么会发生错误。
为了测试我在scope.Complete()语句之前和之后抛出了异常 我在scope.Complete()之前立即发出了故意错误。页面中没有错误,也没有记录ELMAH错误 我在scope.Complete()之后立即发出故意错误。我得到的范围已经完成了最后一次捕获的错误。
我无法弄清楚什么会使PROMOTE尝试发生,以及为什么会发生这种情况 该网站运行了10天,然后我们收到此错误,之后每个人都试图创建一个帐户。 虽然数据库的其他部分工作正常。只是这个函数搞砸了,直到我们重新启动SQL Server。

1 个答案:

答案 0 :(得分:3)

尝试为记录呼叫执行此操作:

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

我认为您的日志记录调用正在尝试升级到分布式事务(当您尝试命中错误记录器时)。此代码将记录调用退出事务。在进行分布式工作时,我对记录器遇到了同样的问题。我会得到一个错误,失败然后记录,然后退出范围并回滚所有内容。