Adding a boundary-event to a tasks implicit ally creates a scope around it. So all processes that are running in the old-version and are waiting in the task that has a boundary-event in the new version, won't work. There is no workaround for this, as the scope is created when the task is created. Only thing you can do is, in your new process, have a user-task without a boundary-event and an identical user task with the boundary-event after it. After changing version, complete all those tasks to force to move into the "userTaskWIthBoundary". Finally, you can deploy yet another version of the definition (without the duplicate users task, only the "userTaskWIthBoundary" remains) to make sure new processes don't have the "two user tasks" hack in them.
It's possible to add an execution-listener to the new process-defintion. When the process ends, the listeners are fetched from the process-definition attached -> which is the new version.