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

发布于 2024-10-04 13:54:16 字数 2503 浏览 1 评论 0原文

我有一个 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;
  }
}

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

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 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

漆黑的白昼 2024-10-11 13:54:21

尝试对您的日志记录调用执行此操作:

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文