带有Membership和Roles的TransactionScope在同一个块中调用(只使用一个连接的方式?)

时间:2011-06-06 20:03:07

标签: c# membership roles transactionscope

我在同一个事务范围内调用了Membership API和Roles API。我已经读过,打开多个连接会导致升级,需要启用分布式事务,因此我正在寻找一种方法来打开一个连接并与之共享:成员身份,角色,我自己的呼叫。

以下是导致不必要升级的工作代码:

public static void InsertUser(string userName, string email, string roleName, int contactId, string comment)
      {
         /*
          * Exceptions thrown here are caught in the DetailView's event handler and piped to the UI.
          */

         using(var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
         {
            string password = Membership.GeneratePassword(Membership.MinRequiredPasswordLength, Membership.MinRequiredNonAlphanumericCharacters);
            const string passwordQuestion = "Should you change your password question?";
            const string passwordAnswer = "yes";
            MembershipCreateStatus status;
            MembershipUser user = Membership.CreateUser(userName, password, email, passwordQuestion, passwordAnswer, true, out status);

            if(user == null)
            {
               throw new Exception(GetErrorMessage(status));
            }

            // Flesh out new user
            user.Comment = comment;
            Membership.UpdateUser(user);

            // Give user a role
            Roles.AddUserToRole(user.UserName, roleName);

            // Create bridge table record
            Guid userId = (Guid)ExceptionUtils.ThrowIfDefaultValue(user.ProviderUserKey, "ProviderUserkey is null!");
            insertIntoAspnet_Users_To_Contact(userId, contactId);

            // Send welcome email
            EmailUtils.SendWelcomeEmailFromAdmin(userName, email, password, passwordQuestion, passwordAnswer, roleName);

            transactionScope.Complete();
         }
      }

由于

2 个答案:

答案 0 :(得分:2)

如果您拥有SQL2008或更高版本,它可以跨多个连接处理事务,而不会升级到MSDTC。要求是对所有连接使用完全相同的连接字符串。

如果你使用较低的SQL服务器版本,我认为你松了。几个月前我调查了这个并发现无法处理它,所以我最终跳过了事务并实现了我自己的错误处理。客户有SQL2005,无法升级。

答案 1 :(得分:0)

您指定了TransactionScopeOption.RequiresNew,这意味着每次传入该段代码时想要一个新事务,即使已经存在合适的环境代码。

这样做:

using(var transactionScope = new TransactionScope())