Updated at the bottom
Concurrent/parallel execution is not a particularly hot topic in SSIS. In the future I expect functionality to be introduced into SSIS to enable things such as spreading parallel executing tasks over multiple boxes and seperating data in the data-flow over multiple boxes. Until then though I shall sit and hope.
In the meantime, its obvious that concurrency can be achieved currently by executing tasks in parallel or having multiple data paths in a data-flow. However, you should also be aware that it is possible to run whole packages in parallel by executing them from the Execute Package Task.
Taking this one step further, its also possible to execute a package in parallel with itself. This could be useful if, for example, you wanted to run a package on multiple disparate but identical sources in parallel. Its this scenario of executing a package in parallel with itself that I want to expand on a little bit here. There are a couple of things you should be aware of if you intend to attempt this.
Cannot distinguish between tasks in the concurrent packages
A fairly common approach to logging in SSIS is to have a parent package catch all events fired by itself and all descendant packages. The method of distinguishing different events fired by the same container is to use the @[System::SourceID] variable which contains the global unique identifier of the container raising the event.
However, if the package is running concurrently with itself events fired by containers in those seperately executing packages will be raised with the same value in @[System::SourceID]. It is quite conceivable that you may want to track all events raised by the same container and in this concurrent execution scenario you are going to run into problems.
For example, you have a custom logging method for which you want to insert a record in an audit table when a container starts to execute and then update that record with the container execution duration when the container completes. If multiple instances of a package were executing concurrently then you would not be able to tie the OnPreExecute and OnPostExecute events fired by the same container together.
I have heard there are plans afoot for a future version of SSIS in which a ForEach loop can execute all of its iterations in parallel. This would cause more problems of the type already explained.
There is not really a workaround to this anomoly. It is just something that you need to be aware of.
Checkpoints files cannot be shared
Another problem regarding a package being executed multiple times is that any checkpoint files created by the package would not, by default, be attributed to a specific execution instance of that package. Hence you have the situation where a package could incorrectly use a checkpoint file that it was not supposed to.
There IS a workaround to this problem. If you can give each execution instance some form of ID (typically passed from a parent package) that will be repeated when that instance of the package is next fired. That ID could be concatenated to the name of the checkpoint file using an expression, thus making a checkpoint file execution dependant!
These are just some random musings. Perhaps they might help people be aware of some issues they may enounter when calling packages multiple times.
-Jamie
Update:
Joachim made a good point in the comments section below. The @[System::ExecutionInstanceGUID] variable can be used to distinguish between different executions of the same package.
Unfortunately this wouldn't be any good in the situation where a package is called multiple times from the same parent package that is used for centralised logging. This is because any reference to that variable in the parent package would use @[System::ExecutionInstanceGUID] that is scoped to the parent package.
This variable could also not be used in the name of a checkpoint file because system variables are not persisted to a checkpoint file and hence each execution of a package would have a different @[System::ExecutionInstanceGUID].
No doubt there are situations where @[System::ExecutionInstanceGUID] would prove useful and indeed Joachim states that he is using them successfully.
Definately something to be aware of! Thanks for the comment Joachim!
-Jamie