ASP.NET Web Forms和MySql Entity Framework:"不支持嵌套事务"

4
我有一个ASP.NET Web Forms应用程序,使用MySql Entity Framework的.Net Connector。
我以前使用过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)
1个回答

6
您可能遇到了MySQL Connector/NET中的此错误
触发此错误的原因:
  1. 代码调用执行查询A
  2. 事务1启动查询A
  3. 执行查询A并在MySQL中引发错误
  4. 事务1没有回滚
  5. 代码调用执行查询B
  6. 事务2启动查询B
  7. MySQL Connector/NET抛出异常
该错误在第4点:在错误后事务1未关闭(或者至少连接器仍然认为它未关闭)。由于连接池,调用查询A和查询B的代码可能完全不相关。另外,如果第4点和第5点之间的时间足够长,则事务将被回滚,因此这种错误很少且随机发生。
不幸的是,MySQL目前还没有修复此问题。我所知道的唯一解决方法是下载Connector/NET的源代码并自行修复/构建它。

谢谢你提供的信息,我认为你是正确的。最终我也做了这个;我的大部分问题都与MySql成员资格提供程序有关,所以我使用了他们的源代码,并删除了一些我不需要的查询。虽然我仍然有这个问题,但现在它发生的频率要少得多,所以我不太担心了。 - barrett777

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接