ASP.NET Web窗体和MySqlentity framework:“不支持嵌套事务”

我有一个ASP.NET Web表单应用程序,使用.Net Connector for MySql Entity Framework。

我以前使用MySql创建了一个Web应用程序,但从未遇到过这个问题。

我目前每天获得大约20000次页面浏览量,并且每天大约有10次“嵌套交易”错误不受支持。

我无法弄清楚它为什么会发生,为什么它只会偶尔发生一次。

在主页面预加载事件中,我获得用户的整数ID并将其保存到公共变量:

using (var entity = new Entities()) { var user = entity.my_aspnet_users.Single(i => i.name == Context.User.Identity.Name); UserID = user.id; if (HttpContext.Current.Request.Url.AbsolutePath != "###" && HttpContext.Current.Request.Url.AbsolutePath != "###") { if (user.Player == null) Response.Redirect("###", true); else PlayerID = user.Player.PlayerID; } } 

然后在页面上:

 using (var entity = new Entities()) if (entity.Players.Count(i => ###) == 1) { var user = entity.my_aspnet_users.Single(i => i.id == Master.UserID); if (user.Player == null) { user.Player = entity.Players.Single(i => ###); entity.SaveChanges(); } Response.Redirect("###", false); } 

SaveChanges()会抛出错误。 我不知道为什么它有时会发生。 当用户在网站上注册时,我有时会得到相同的错误,尽管所有这些似乎是随机且罕见的。

无论如何,我认为在MySql中允许嵌套事务? 我需要设置一个设置吗? 我的MySql实例是5.6.17,我相信使用默认参数 – 在Amazon RDS中设置。

‘User.Identity.Name’是否可以访问数据库? 你知道我在哪里可以解决这个问题吗?

如果有帮助,这里是一些例外的堆栈跟踪:

 **Exception on example code:** System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Data.Entity.Core.EntityException: An error occurred while starting a transaction on the provider connection. See the inner exception for details. ---> System.InvalidOperationException: Nested transactions are not supported. at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception) at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex) at MySql.Data.MySqlClient.MySqlConnection.BeginTransaction(IsolationLevel iso) at MySql.Data.MySqlClient.MySqlConnection.BeginDbTransaction(IsolationLevel isolationLevel) at System.Data.Common.DbConnection.BeginTransaction(IsolationLevel isolationLevel) at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.b__0(DbConnection t, BeginTransactionInterceptionContext c) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.BeginTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext) at System.Data.Entity.Core.EntityClient.EntityConnection.c__DisplayClassf.b__d() at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation) at System.Data.Entity.Core.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel) --- End of inner exception stack trace --- at System.Data.Entity.Core.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel) at System.Data.Entity.Core.EntityClient.EntityConnection.BeginTransaction() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction) at System.Data.Entity.Core.Objects.ObjectContext.c__DisplayClass2a.b__27() at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation) at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction) at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Data.Entity.Internal.InternalContext.SaveChanges() at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() at System.Data.Entity.DbContext.SaveChanges() at ###.Account.###.ButtonSubmit###_Click(Object sender, EventArgs e) at System.Web.UI.WebControls.Button.OnClick(EventArgs e) at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.HandleError(Exception e) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest() at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) at System.Web.UI.Page.ProcessRequest(HttpContext context) at ASP.account_###.ProcessRequest(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) **Exception on creating a user:** System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.InvalidOperationException: Nested transactions are not supported. at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception) at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex) at MySql.Data.MySqlClient.MySqlConnection.BeginTransaction(IsolationLevel iso) at MySql.Data.MySqlClient.MySqlConnection.BeginTransaction() at MySql.Web.Security.MySQLMembershipProvider.GetUser(Object providerUserKey, Boolean userIsOnline) at MySql.Web.Security.MySQLMembershipProvider.GetUser(String username, Boolean userIsOnline) at MySql.Web.Security.MySQLMembershipProvider.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, Object providerUserKey, MembershipCreateStatus& status) at System.Web.UI.WebControls.CreateUserWizard.AttemptCreateUser() at System.Web.UI.WebControls.CreateUserWizard.OnNextButtonClick(WizardNavigationEventArgs e) at System.Web.UI.WebControls.Wizard.OnBubbleEvent(Object source, EventArgs e) at System.Web.UI.WebControls.CreateUserWizard.OnBubbleEvent(Object source, EventArgs e) at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) at System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e) at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.HandleError(Exception e) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest() at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) at System.Web.UI.Page.ProcessRequest(HttpContext context) at ASP.register_aspx.ProcessRequest(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

您可能在MySQL Connector / NET中遇到此错误 。

什么触发了这个bug:

  1. 代码调用执行查询A.
  2. 启动查询A的事务1
  3. 执行查询A并导致MySQL出错
  4. 事务1不会回滚
  5. 代码调用执行查询B.
  6. 启动查询B的事务2
  7. MySQL Connector / NET抛出exception

错误是第4点:事务1在发生错误后保持打开(或者至少连接器仍然确信它保持打开状态)。 由于连接池,调用查询A和查询B的代码可以完全不相关。 此外,如果第4点和第5点之间的时间足够长, 回滚事务,因此稀有性和随机性。

不幸的是,MySQL还没有修复。 我所知道的唯一解决方法是下载Connector / NET的源代码并自行修复/构建它。