Multiple Manager commits with TransactionManager
I have been spending a few days searching for documentation or a solution for my problem.
I am running version 6.1.
I have multiple managers, UserManager, UserProfileManager, RoleManager; all have been initialized with the GetManager(null, "transactionID"). When registering a user there are multiple other things I want to do in the same transaction.
I have some example code (this works, a user is created with the correct roles)
MembershipCreateStatus status;
user = userManager.CreateUser(userName, password, email, "", "", true, null, out status);
if (user == null)
throw new Exception(status.ToString());
user.IsBackendUser = false;
//Add User Role by default
var userAppRole = roleManager.GetRole("Users");
roleManager.AddUserToRole(user, userAppRole);
//Add other Roles
if (rolesToAdd != null)
rolesToAdd.ForEach(o =>
user.AddRoleToUser(o, sfRoleManager);
);
TransactionManager.CommitTransaction(transactionString);
When I add a new sitefinity userprofile to the transaction with the amended code below the transaction commit throws a timeout sql exception.
MembershipCreateStatus status;
user = userManager.CreateUser(userName, password, email, "", "", true, null, out status);
if (user == null)
throw new Exception(status.ToString());
user.IsBackendUser = false;
//Add User Role by default
var userAppRole = roleManager.GetRole("Users");
roleManager.AddUserToRole(user, userAppRole);
//Add other Roles
if (rolesToAdd != null)
rolesToAdd.ForEach(o =>
user.AddRoleToUser(o, sfRoleManager);
);
//And the Sitefinity profile
var profile = userProfileManager.CreateProfile(user, typeof(SitefinityProfile).FullName);
profile.SetValue("FirstName", firstName);
profile.SetValue("LastName", lastName);
profile.SetValue("Nickname", nickName);
TransactionManager.CommitTransaction(roleManager.TransactionName);
When the user profile is added to the transaction it fails with the following exception:
Error executing query: Telerik.OpenAccess.RT.sql.SQLException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception: The wait operation timed out
UPDATE:
I have checked out docs.sitefinity.com/for-developers-create-users to see the workflow for best practices but what happens if the profile savechanges fails? The user will be without a profile? This is why I want to use the transaction. In my case the profile save is failing and causing weird domain logic issues.
Hi ,
All the managers should be initialized using the transaction. This way they will operate in one transaction. Example:
using System;using System.Web.Security;using Telerik.Sitefinity.Data;using Telerik.Sitefinity.Model;using Telerik.Sitefinity.Security;using Telerik.Sitefinity.Security.Model;namespace SitefinityWebApp public partial class TransactionManagerWebForm : System.Web.UI.Page protected void Page_Load(object sender, EventArgs e) string transactionName = string.Format("createUser_0", Guid.NewGuid()); UserManager userManager = UserManager.GetManager(UserManager.GetDefaultProviderName(), transactionName); MembershipCreateStatus status; string userName = "testUser"; string password = "password"; string email = "testUser@mail.com"; User user = userManager.CreateUser(userName, password, email, "", "", true, null, out status); if (user == null) throw new Exception(status.ToString()); user.IsBackendUser = false; RoleManager roleManager = RoleManager.GetManager("AppRoles", transactionName); //Add User Role by default var backendUserRole = roleManager.GetRole("BackendUsers"); roleManager.AddUserToRole(user, backendUserRole); UserProfileManager userProfileManager = UserProfileManager.GetManager(UserProfileManager.GetDefaultProviderName(), transactionName); //And the Sitefinity profile var profile = userProfileManager.CreateProfile(user, typeof(SitefinityProfile).FullName); profile.SetValue("FirstName", userName); profile.SetValue("LastName", userName); profile.SetValue("Nickname", userName); TransactionManager.CommitTransaction(transactionName);