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