开发者

TransactionScope with Membership and Roles calls in same block (way to use only one connection?)

I have calls to the Membership API and the Roles API in the same transaction scope. I've read that opening more than one connection causes escalation r开发者_如何学Goequiring distributed transactions to be enabled, so I'm looking for a way to open one connection and share it with: Membership, roles, my own calls.

Here's the working code that causes unwanted escalation:

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();
         }
      }

Thanks


If you have SQL2008 or higher, it can handle a transaction across multiple connections, without escalating to MSDTC. The requirement is that you use exactly the same connection string for all connections.

If you're on a lower SQL server version I think that you loose. I investigated this a few months ago and found no way to handle it, so I ended up skipping the transactions and implementing my own error handling instead. The customer had SQL2005 and an upgrade was not possible.


You specified TransactionScopeOption.RequiresNew, which means you want a new transaction each time you pass in that piece of code, even if there is already a suitable ambient one.

Just do this:

using(var transactionScope = new TransactionScope())
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜