【发布时间】:2011-10-24 20:55:28
【问题描述】:
我们正在尝试使用 System.Transactions.TransactionScope 将 System.Web.Providers 成员管理集成到事务中,并不断收到以下错误消息:
The operation is not valid for the state of the transaction.
在异常中包含以下更令人困惑的消息:
The provider did not return a ProviderManifestToken string.
在任何人问之前,是的,我们已经验证了连接字符串是正确的,并且我们用来连接数据库的用户具有适当的权限。如果我们尝试从 TransactionScope 块中调用 Membership.CreateUser() ,它会起作用。把它放在一个 TransactionScope 中,它就会失败。
关于 Universal Provider 的信息似乎少得惊人。您所看到的几乎都是 NuGet 页面的链接和 Scott Hanselman 六月的博客文章。
有没有人知道如何让 System.Web.Providers 参与交易?
谢谢。
这是完整的堆栈跟踪,以防有用:
System.Data.ProviderIncompatibleException was unhandled by user code
Message=The provider did not return a ProviderManifestToken string.
Source=System.Data.Entity
StackTrace:
at System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection)
at System.Web.Providers.Entities.ModelHelper.GetStorageMetadata(String providerName, DbConnection connection, String ssdl)
at System.Web.Providers.Entities.ModelHelper.CreateMetadataWorkspace(String providerName, DbConnection connection, String csdl, String ssdl, String msl)
at System.Web.Providers.Entities.ModelHelper.CreateEntityConnection(ConnectionStringSettings setting, String csdl, String ssdl, String msl)
at System.Web.Providers.Entities.ModelHelper.CreateMembershipEntities(ConnectionStringSettings setting)
at System.Web.Providers.DefaultMembershipProvider.Membership_CreateUser(String applicationName, String userName, String password, String salt, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, DateTime& createDate, Boolean uniqueEmail, Int32 passwordFormat, Object& providerUserKey)
at System.Web.Providers.DefaultMembershipProvider.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, Object providerUserKey, MembershipCreateStatus& status)
at System.Web.Security.Membership.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, Object providerUserKey, MembershipCreateStatus& status)
at WcfLoginRegister.RegistrationService.RegisterUser(RegisterUserRequest request) in C:\Users\rmacgrogan\dev\pallas\parthenon\sandbox\FbEntityTypeTester\WcfLoginRegister\RegistrationService.svc.cs:line 43
at SyncInvokeRegisterUser(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
InnerException: System.Transactions.TransactionException
Message=The operation is not valid for the state of the transaction.
Source=System.Transactions
StackTrace:
at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction)
at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification)
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.SqlClient.SqlProviderServices.UsingConnection(SqlConnection sqlConnection, Action`1 act)
at System.Data.SqlClient.SqlProviderServices.UsingMasterConnection(SqlConnection sqlConnection, Action`1 act)
at System.Data.SqlClient.SqlProviderServices.GetDbProviderManifestToken(DbConnection connection)
at System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection)
InnerException:
更新
我做了一个简化的测试来更好地访问真正的潜在错误,Bahri Gungor 是正确的,根本问题是未启用 MSDTC。
但是,由于我试图在 Azure 项目中运行此代码,并且由于 Azure 不支持分布式事务,因此我无法使用丑陋的解决方法。所有成员写入必须发生在单独的事务中,这很不幸。
感谢大家的帮助。
【问题讨论】:
-
我想知道你是否可以发布你想要做的代码?
-
你能贴出你用来打电话给
Membership.CreateUser()的代码吗? -
问题的根源在于内部异常。这是一个非常通用的异常,意味着底层事务存在一些问题……这可能意味着 MSDTC 未运行或不可访问(防火墙等)。你能尝试一个带有事务范围的简单“纯”SQL 操作,看看它是否有效吗?它也可能由于超时而发生。请参阅msdn.microsoft.com/en-us/library/… 更改默认 tx 超时
-
您是否正确配置了组件服务以允许 MSDTC 事务?
标签: c# transactions asp.net-membership