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 requiring 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.