Hey
Aaron Mulder wrote:
> ... with every spec I read. I'm through JMX, JTA,
> and JDBC standard extension so far...
Those are the core specs for this task, yes. Looking through EJB and JTS
would help too..
> I haven't tried to fit into the JDBC connection pooling mechanism,
> since I had planned to use this outside of the context of an application
> server as well (and thus, it should be useful without a PooledDataSource
> or whatever). I may have to rethink that - I'm not sure I can make a
> clean split between the transactional capabilities and the "dumb"
> implementation.
I think you can. :-) It takes some thought, but it can be done.
> In any case, it seems like I have further transactional problems.
> According to the JDBC spec, I think this is what is supposed to happen:
>
> 1) Bean requests connection
> 2) Pool generates connection
A pool connection mind you.
> 3) XAResource is associated with connection
Through XAResource.start(), yes.
> 4) XAResource is registered with TransactionManager (seems to be via
> Transaction.enlistResource)
Yup.
> 5) TransactionManager calls start(...) on XAResource (not my problem)
As in 3, although I think this *is* your problem. When a bean does
"getConnection" you do start() and when it does "close()" you do end().
> 6) Connection is returned to bean
> 7) Connection behavior is different depending on whether it currently is
> or is not part of a global transaction. According to the JDBC spec (7.5):
> "A TX_BEAN_MANAGED bean may even use the same JDBC Connection both inside
> and outside of a global transaction." - which seems to mean that for every
> relevant method invocation (commit, rollback, setAutoCommit), the
> connection must determine from the XAResource whether it is or is not
> currently part of a global transaction (how?).
The pool will have to integrate with the TransactionManager and call
getStatus() to see if there's a tx or not.
> 8) Bean calls close on connection. Connection is left in limbo (not in
> use, not in pool)
IMHO the connection *should* be placed in pool after you call end() on
it. However, since JDBC 1.0 drivers don't understand this (no
XAResource) there should be a wrapper driver that on end() hangs on to
it (until commit/rollback). But your pool should be expecting JDBC 2.0
(IMHO at least). I think this will be the easiest/cleanest, or otherwise
you'll end up with a lot of exceptions ("if JDBC 1.0 driver do this,
else this").
> 9) TransactionManager calls commit/rollback methods on XAResource
> (not my problem)
Correct.
> 10) XAResource calls appropriate commit/rollback methods on connection and
> returns connection to the pool.
There's no way for you to know that these methods have been called.
Remember, XAResource belongs to the driver, and it doesn't know anything
about your pooling. You could register a tx synchronization listener
though, which could do this (tied up->pool).
> I'm really unsure about point #8. If the bean calls close() on
> the connection, the JTA spec (3.4.2) seems to indicate that the connection
> should be dissociated from the transaction, without ending the transaction
> (does that imply a commit or rollback?
ending tx -> commit or rollback, yes. Disassociation is done through
"end()" call on XAResource.
> ), and then returned to the pool of
> available connections. So then the only way for a bean's work to get
> committed is for the bean to never call close(), so that the
> TransactionManager does the commit - but then how do you know when to
> release the connection back to the pool?
As above, the pool could use a tx synchronization listener and do this
on afterCompletion().
(BTW, this is how the EJB server knows that tx's are being commited, so
that it can call ejbStore on beans before commiting JDBC connections).
> Can you assume that when the
> XAResource's end method is called (indicating the end of a transaction),
> the connection is returned to the pool?
IMHO: Yes! And "end" should be called when bean does "close" on your
wrapper connection.
> This seems contrary to the part
> of the JTA spec (3.4.4) that talks about how a resource can be associated
> with several transactions over time.
Does it?? A con is retrieved, used with a tx, put back into pool, and
repeat.
> On to other problems. If I understand this right, the
> connection/XAResource never initiates a transaction. Either the container
> initiates a transaction before the bean ever requests the connection, or
> the bean is responsible for all transactional boundaries (and must
> manually commit or rollback on the connection).
Correct.
> So other than confirming the sequence above, I have one major
> question left. The only place we can run into trouble (that is, a
> connection isn't committed or rolled back or released to the pool for a
> long period of time - say, 20+ minutes) is when the clients or beans
> manage their own transactions (is this distinct from bean-managed
> persistance?).
We can detect this case actually. If a bean should manage its own
transactions, and a method is called that has no tx associated with it,
but one is running on return, we can know that it hasn't ended the tx
properly and can thus complain. So tx's will always be closed properly
regardless of mode (container mgd, or bean mgd).
> In that case, it's not clear whether an XAResource would
> be necessary. Can a bean create a UserTransaction and get a connection
> and then register the connection's XAResource with the UserTransaction?
UserTransaction has no means to register XAResources...
> If
> so, then there needs to be a public way to get an XAResource, and if not
> the XAResource can be managed entirely within the container.
There is no way to publically get an XAResource. The connections you
provide through the pool does not implement XAConnection. They're plain
connections, but the underlying stuff knows all about tx's.
> In any case, I suppose the connection and XAResource should both
> be wrappers around the physical databsae connection.
Only the connection. The user should not see the XAResource.
Ok, there's lots of stuff to figure out, but you are an a very good
track. Keep at it ;-)
Bang your head against the JTA spec, and the JDBC spec. If you want I
can make a little diagram over which parts (IMHO) should be created, and
how they would relate.
/Rickard
ps. I figure some of these things out as I type. It's non-trivial, oh
yes, but through these kinds of discussions we *are* going to nail this
thing ;-)
--
Rickard �berg
@home: +46 13 177937
Email: [EMAIL PROTECTED]
http://www.telkel.com
http://www.jboss.org
http://www.dreambean.com