I'm reviving this thread because I tried this tenant switch OnProcessStart method and it apparently caused concurrency issues when launching processes.
There's no issue creating a single process at a time, but when I launch, for example, 100 processes in the same second, I start seeing many deadlock errors in the error log and the processes fail to start with this message "Could not execute a built-in/extended action on activity 'Start' (#9750977) because the activity does not exist".
I believe it is because of the tenant switch because removing it stops the deadlocks (although it causes other errors related to data not being visible, since the process is running on the wrong tenant).
João Pedro Abreu wrote:
What version are you on? I tried TenantSwitch in a process in 9.1 a few weeks ago and it wouldn't let me do it at all. Since processes are tied to tenants, that error message makes perfect sense.
I'm on 9.1.501.0.
The OnProcessStart event of a process is the only point where a tenant switch works. Anywhere else throws an error.
From what I saw, doing a tenant switch inside OnProcessStart will cause the platform to update the tenant_id on the process and on its underlying activities. This works well for low concurrency scenarios, but if there are many processes being updated concurrently, it will cause deadlocks.
In the database I could see many instances where statements like this one:
UPDATE OSSYS_BPM_PROCESS_INPUT SET TENANT_ID = @NEWTENANTID WHERE PROCESS_ID = @PROCESSID AND TENANT_ID = @OLDTENANTID
Were being blocked by statements like this one:
SELECT ACTIVITY_DEF_ID, PROCESS_ID, USER_ID, STATUS_ID, IS_RUNNING_SINCE, IS_RUNNING_AT, NEXT_RUN, PRECEDENT_ACTIVITY_ID, PRECEDENT_OUTCOME, DUE_DATE FROM OSSYS_BPM_ACTIVITY WITH ( UPDLOCK ) WHERE TENANT_ID = @TENANTID AND ID = @ACTIVITYID
I ended up copying all the code I needed the process to execute to a new eSpace and exposing the tenant IDs on all the entities, so the process could run without the need for a tenant switch.
For future reference, I tried creating a semaphore (by obtaining an exclusive table lock, held until the end of the transaction, on a dummy table) before doing the a tenant switch. It solved the deadlocks, but caused some processes to fail the Start activity and not retr ity, becoming stuck.