Hi *,
I have build up an application that consists of several OSGi bundles
providing different kinds of rather basic services (e.g. user
management, dynamic security management, messaging, ...). Now I've also
got a BPMN 2.0 process engine into the mix which is used to do some
higher-level work.
Let's have a simple example:
Assume the following basic services (hybrid; OSGi/EJB+JPA):
* A
* B
* C
...now we have the business process engine:
* P
...and let's also have a web frontend that includes some EJBs as well:
* W
...now let's do something:
1. incoming request to W <-- TX start
2. W call P.start()
3. P creates new process instance <-- TX reuse (datasource P-DS)
4. P calls A.something() <-- TX reuse (datasource A-DS)
5. P saves state <-- TX reuse (datasource P-DS)
6. P calls B.something() <-- TX reuse (datasource B-DS)
7. P saves state <-- TX reuse (datasource P-DS)
8. P calls C.something() <-- TX reuse (datasource C-DS)
9. C.something fails <-- TX rollback (all datasources)
Now, the problem is, that a new process is started within the existing
thread, which is nice from a performance- and resource-point-of-view.
However, as the process engine and most of the basic services have their
own datasource configured as well as completely separate JPA entity
managers (almost all my services are EJB-based), it turned out that I
have to configure all of them as being XA-datasources.
This is what I want to avoid completely as it means that, unless I
configure every basic service EJB implementation to enforce a new
transaction, everything that is executed by the initial thread gets
rolled back as well, if some error occurs inside a service call. This
obsoletes the use of the process engine a bit, because then you don't
know exactly where inside the process execution something went bad.
Additionally, all the EJBs are being secured using the standard
annotations but the process engine itself should run using its own user
without and security permissions to EJBs by default. The actual
permissions are granted using a SUDO style when calling some OSGi
service which is determined from the user that initially started a new
process. This way I can plug in external systems without any special
permissions to e.g. continue a process using a BPMN 2.0 user task.
So I thought at first that a new thread pool might help, which turns out
to be a very bad idea as it made things worse.
Now I think about introducing a custom GlassFish thread pool that is
used to execute the separate service calls during process execution. But
I have to be sure that this GlassFish managed thread pool is picking up
the correct transactional and security-wised context at every new call.
I have my doubts here, as the TX and JAAS/JACC stuff seems to be
implemented using either ThreadLocal or - even worse -
InheritableThreadLocal (in the latter case the first thread created by
the thread-pool would inherit something and never lose it and not
getting reset on every new incoming work request).
If this is not doable I have to implement some other kind of TX and
JAAS/JACC "barrier" to implement default behavior.
Thanx for any pointers,
Ancoron