More in this section
Forums / Developing with Sitefinity / Multiple Manager commits with TransactionManager

Multiple Manager commits with TransactionManager

The forums are in read-only mode. In case that you want to directly contact the Progress Sitefinity team use the support center. In our Google Plus group you can find more than one thousand Sitefinity developers discussing different topics. For the Stack Overflow threads don’t forget to use the “Sitefinity” tag.
2 posts, 0 answered
  1. Liquid
    Liquid avatar
    3 posts
    Registered:
    05 Apr 2013
    27 Oct 2015
    Link to this post

    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
       --- End of inner exception stack trace ---

     

    UPDATE:

    I have checked out http://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.

  2. Nikola Zagorchev
    Nikola Zagorchev avatar
    424 posts
    Registered:
    19 Apr 2017
    29 Oct 2015
    Link to this post
    Hi Liquid,

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


    Regards,
    Nikola Zagorchev
    Telerik
     
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
     
2 posts, 0 answered