on 11-04-2010 7:07 PM
<<Text removed by moderator>>
I am working with a highly multithreaded application which wants to create users in bulk or one at a time as they are requested. Imagine a system which takes bulk uploads (in parallel) of user creation requests and tries to create them as fast as possible.
I have code that works, but I am thinking that I am not doing this in the best way possible. Basically, I find that I have to try to create the record up to 10 times, and if all 10 attempts fail, then give up. This seems very expensive and error prone.
I think the problem is that I don't really follow how the "ChangeStamp" stuff works, or why it is even required. I understand the concept of getting a unique key for an insert statement for parallel processes, but surely MDM offers a better way to insert a user to a repository?
When I run the below process, 5 at a time, normally, one of the processes will fail with the below error.
com.sap.mdm.commands.CommandException: com.sap.mdm.intern.protocol.manual.ServerException: MDM repository data is out-of-date or is locked by another MDM Server. Refresh the data and try the operation again. If the error persists, contact the system administrator. [0xffab4128]
at com.sap.mdm.intern.protocol.manual.AbstractProtocolCommand.execute(PassportSupport passportSupport)
So, my questions are this:
1. Is "InChangeStamp" really required? If so, why?
2. If so, am I getting the InChangeStamp the best way possible? Executing a GetUserListCommand seems like a very expensive and risky way to get a value just to add a user record?
The code:
// Get a u201Ccontextu201D, whatever that is?
RepSessionCtx = new RepositorySessionContext(u201CServeru201D, u201CRepositoryu201D, u201CUseru201D);
// Get an actual session connection
RepSession = SessionManager.Instance.createSession(RepSessionCtx, SessionTypes.REPOSITORY_SESSION_TYPE, u201Cpasswordu201D);
// Get a CreateUserCommand
CreateUserCommand cmd = new CreateUserCommand(RepSessionCtx);
cmd.Session = RepSession;
// Set the user
cmd.User = newUser;
cmd.User.setPassword("PASSWORD");
// Get a new user ID for the command
UserId uid = cmd.getNewUserId();
// Get a valid InChangeStamp <-- not sure what exactly InChangeStamp is?
GetUserListCommand userListCmd = new GetUserListCommand(mSession.RepSessionCtx);
//Console.WriteLine("outer attempt " + i);
for (int i = 0; i < 10; i++)
{
try // Try very fast up to 10 times to get a unique valid inchangestamp
{
userListCmd.execute();
cmd.InChangeStamp = userListCmd.getChangeStamp();
cmd.execute();
userCreated = true;
break; // Successful
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
//Console.WriteLine("Could not create the user at " + i);
}
}
Edited by: Wardell Castles on Nov 4, 2010 3:10 PM
Edited by: Matt on Nov 10, 2010 4:30 PM
Ok, I think I can narrow this down to a more simple question:
I have a highly threaded application where multiple threads are trying to create users. In each thread, I get a repository session, and within the thread try to create the user like below:
RepSessionCtx = new RepositorySessionContext(u201CServeru201D, u201CRepositoryu201D, u201CUseru201D);
RepSession = SessionManager.Instance.createSession(RepSessionCtx, SessionTypes.REPOSITORY_SESSION_TYPE, u201Cpasswordu201D);
CreateUserCommand CreateUsercmd = new CreateUserCommand(RepSessionCtx);
GetUserListCommand userListCmd = new GetUserListCommand(mSession.RepSessionCtx);
userListCmd.execute(); // <-- THIS SEEMS LIKE A VERY BAD WAY TO GET A CHANGESTAMP TO CREATE A USER?!
CreateUsercmd.InChangeStamp = userListCmd.getChangeStamp();
CreateUsercmd.execute(); // <-- ERROR THROWN HERE!!!
It seems that my CreateUsercmd will not run, because some other thread has grabbed its ChangeStamp before it runs?!
The error is:
com.sap.mdm.intern.protocol.manual.ServerException: MDM repository data is out-of-date or is locked by another MDM Server. Refresh the data and try the operation again. If the error persists, contact the system administrator. [0xffab4128]
at com.sap.mdm.intern.protocol.manual.AbstractProtocolCommand.execute(PassportSupport passportSupport)
But if I try to run the above code in a loop, say 10 times, it normally will end up working.
What do I do to create a user reliably in my thread?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
86 | |
10 | |
10 | |
9 | |
7 | |
7 | |
6 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.