-
1. Re: CachedConnectionManager implementation
adrian.brock Jan 7, 2005 5:47 PM (in response to adrian.brock)What is really required is a pattern that comes up a lot,
but we currently have no direct implementation for it.
It is the combined Transaction/InvocationContext pattern.
i.e. When we have a transaction state should be synchronized with it.
When there is no transaction state should tidied up when the invocation finishes.
There are extra complications relating to recursive calls, e.g. Entity re-entrance.
The pattern also needs to take into account singletons like Servlets and JMX
when outside the EJB context. -
2. Re: CachedConnectionManager implementation
adrian.brock Jan 7, 2005 5:54 PM (in response to adrian.brock)I will call this pattern InvocationContextLocal.
A simple/naive implementation is:
Add an interceptor before the transaction interceptor that maintains a thread local
stack of invocation contexts.
Each part of the system will use its own "slot" in the invocation context to store state.
It can also define its own order of close context processing.
In the transaction demarcation interceptor "enlist" this context in the transaction
for synchronization at commit/rollback.
On the invocation return stroke close the context (unless it was enlisted
in a transaction).
If there is a transaction, the transaction synchronization does the context close
processing. -
3. Re: CachedConnectionManager implementation
adrian.brock Jan 7, 2005 6:03 PM (in response to adrian.brock)Obvious problems with this approach:
1) Every invocation needs to establish an invocation context on the off chance
one is needed.
2) When outside a transaction, state will be cleaned up later than what is done now
(which is done in each interceptor).
The reason for not doing it in an interceptor is that we want to control the order
of cleanup. e.g. we don't want to release the entity lock until we have finished
checking all the connections have been closed. But we don't do that until
the db synchronize has been performed.
Logically, the invocation context interceptor would be better placed after the
Lock/Instance/Reentrance interceptors. Especially since the instance interceptor
is what gives us the object instance.
But the problem with doing that is that the context on the thread local stack
is cleaned up too early. Meaning transaction synchronization uses the wrong context.
We cannot defer the cleanup to transaction synchronization since this invocation
might not be the demarcation point of the transaction. -
4. Re: CachedConnectionManager implementation
bill.burke Jan 7, 2005 10:58 PM (in response to adrian.brock)These seem like separate problems that should be solved in different places.
2 and 3 seem like they should be implemented at the JCA level.
For 2, when the connection is accessed, check to see if the current thread is associated with a transaction, if so enlist the connection with the transaction.
For 3, this should also be handled by JCA. If a connection is obtained while within the context of a tx a Tx synchronization should be used to automatically close/release the connection in afterComplete. You shouldn't have to use EJB to get this automatic connection closing. If the connection has already been associated, then there is no need to register this synchronization.
Is the TX still associated with the thread in Synchronization.afterComplete? If so, if somebody calls getConnection within afterComplete, the JCA impl should check to see if the current TX is committed, if so, do not enlist the connection with the TX and treat it as if it was dissassociated.
One other thing on #3. I think it should also allocate an Exception when getConnection() is called. That way, if you as a developer want to find out exactly where a connection was leaked, you can find out by printing the stack trace of all places getConnection() was called and not cleaned up. You cannot do this with the CCM solution currently.
I don't not understand 1/4. I'll have to read the spec. -
5. Re: CachedConnectionManager implementation
adrian.brock Jan 10, 2005 2:45 PM (in response to adrian.brock)"bill.burke@jboss.com" wrote:
These seem like separate problems that should be solved in different places.
2 and 3 seem like they should be implemented at the JCA level.
For 2, when the connection is accessed, check to see if the current thread is associated with a transaction, if so enlist the connection with the transaction.
Enlist which connections? If they are not recorded against the EJB instance
by a context interceptor how do you know the list?
Without an Invocation Context demarcation all you could have is a Thread
list of connections some of which might belong to a previous EJB or WEB
container in the stack.
For 3, this should also be handled by JCA. If a connection is obtained while within the context of a tx a Tx synchronization should be used to automatically close/release the connection in afterComplete. You shouldn't have to use EJB to get this automatic connection closing. If the connection has already been associated, then there is no need to register this synchronization.
Is the TX still associated with the thread in Synchronization.afterComplete? If so, if somebody calls getConnection within afterComplete, the JCA impl should check to see if the current TX is committed, if so, do not enlist the connection with the TX and treat it as if it was dissassociated.
Fine as long as there is a transaction. If there is no transaction they need
closing at end of invocation.
But in both cases only if the EJB instances does not mark them as
unshareable resource-refs. JCA does not know this information without being
told by the EJB/WEB container.
One other thing on #3. I think it should also allocate an Exception when getConnection() is called. That way, if you as a developer want to find out exactly where a connection was leaked, you can find out by printing the stack trace of all places getConnection() was called and not cleaned up. You cannot do this with the CCM solution currently.
Yes you can, since it already does this.