具有两种连接方法的事务范围

发布于 2024-12-16 14:59:14 字数 1311 浏览 0 评论 0原文

我的 ASP.NET MVC 应用程序正在使用应用程序服务作为成员资格。由于多种原因,我没有使用应用程序服务配置文件。我正在管理一堆连接到会员资格表的定制表中的个人资料。 我的域模型由使用实体框架 (DbContext) 映射到我的表(包括配置文件表,但不包括应用程序服务表)的类组成。

当会员资格提供者创建新用户时,我想在我的个人资料表中执行一系列操作,并在任何个人资料准备步骤失败时回滚会员资格创建。

因此,我更改了注册方法,以包含对执行我想要的工作的方法的调用,并将其全部放在 TransactionScope 中。当没有 Transaction 时,代码工作正常,但使用 TransactionScope,一旦从 Repository 类(位于单独的程序集中)调用 context.SaveChanges() 方法,我就会收到错误:“提供程序做了不返回 ProviderManifestToken 字符串。”

using (TransactionScope scope = new TransactionScope())
{
System.Web.Security.MembershipUser newUser = Membership.CreateUser
    (model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);

if (createStatus == MembershipCreateStatus.Success)
{
    FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);

    // Create the profile and permissions
    bool profileCreation = repository.NewUser(newUser.UserName, newUser.ProviderUserKey);

    if (profileCreation)
    {
        scope.Complete();
        return RedirectToAction("List", "Project");
    }
    else scope.Dispose();
}
else
{
    scope.Dispose();
    ModelState.AddModelError("", ErrorCodeToString(createStatus));
}                    
}

事务是否可以处理来自实体框架和应用程序服务代码的数据库连接(我不知道它使用什么连接方法)?如果是这样,我该如何实现这一目标?

我将非常感谢任何帮助, 戴夫

My ASP.NET MVC application is using Application Services for Membership. For a number of reasons I am not using the Application Services Profiles. I am managing profiles in a bunch of bespoke tables that are connected to the Membership tables.
My Domain Model consists of classes that map with Entity Framework (DbContext) to my tables (including profile tables but not the Application Services Tables).

When a new user is created by the membership provider, I want to do a bunch of things in my profile tables and rollback the membership creation if any of my profile preparation steps fails.

So I altered the registration method to include a call to the methods that do the work I want and placed it all in a TransactionScope. The code works fine when there is no Transaction, but using a TransactionScope, as soon as the context.SaveChanges() method is called from within the Repository Class (which is in a separate assembly), I get the error: "The provider did not return a ProviderManifestToken string."

using (TransactionScope scope = new TransactionScope())
{
System.Web.Security.MembershipUser newUser = Membership.CreateUser
    (model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);

if (createStatus == MembershipCreateStatus.Success)
{
    FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);

    // Create the profile and permissions
    bool profileCreation = repository.NewUser(newUser.UserName, newUser.ProviderUserKey);

    if (profileCreation)
    {
        scope.Complete();
        return RedirectToAction("List", "Project");
    }
    else scope.Dispose();
}
else
{
    scope.Dispose();
    ModelState.AddModelError("", ErrorCodeToString(createStatus));
}                    
}

Is it possible for transactions to handle connections to the database that are coming from Entity Framework and the Application Services code (I don't know what connection method it uses)? If so, how do I achieve this?

I would be very grateful for any help,
Dave

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

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

发布评论

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

评论(2

荒芜了季节 2024-12-23 14:59:14

听起来可能 EF 或您的会员提供商未列入交易 (EnlistTransaction)。每个参与者的 SQL 连接是否与同一服务器(显然是不同的数据存储)?您可以尝试仅使用成员资格提供程序或仅使用实体框架来执行事务范围,以查看哪一个造成了问题。

请参阅有关事务范围的帖子用法

您也不需要调用 scope.Dispose(),因为您处于 using 语句中。这是隐式为您完成的。

It sounds like maybe EF or your Membership Provider is not enlisted in the transaction (EnlistTransaction). Are the SQL Connections for each participant to the same server (obviously different data stores)? You could try performing the transaction scope using only the Membership Provider, or only the Entity Framework to see which one is causing the grief.

See this post regarding transaction scope usage.

You also don't need to call scope.Dispose() since you are in a using statement. This is implicitly done for you.

所谓喜欢 2024-12-23 14:59:14

谢谢 SilverNinja 的建议。答案其实很简单:
从“服务”窗口打开分布式事务协调器 (MSDTC)。

Thank you SilverNinja for the advice. The answer turned out to be quite simple:
Turn on Distributed Transaction Coordinator (MSDTC) from the Services window.

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