Details
Description
When the jdbc datastore are integrated with a larger application working against a database we have the case in which the external app is in control of the connection pool and the transaction is controlled outside.
The current jdbc-ng code already avoids grabbing a connection and closing it provided the current transaction already has a connection associated to it.
In the case of external control it would be nice to have a method like createJ2eeTransaction(Connection cx) that has the following features:
- builds a transaction with a user provided connection
- never tries to grab another connection for methods that do get the transaction as a param, and from all the methods in FeatureSource/FeatureStore provided the connection is set
- never closes the connection manually (this is already happening provided the transaction is not AUTO_COMMIT)
- never calls directly commit/rollback
The latter can be achieved if we build a special transaction that never actually calls commit/rollback on the connection. Actually, it would be sufficient that the user never manually calls commit/rollback on the transaction, but let's try to be extra sure about it.
From what I see this would be sufficient to perform an integration into a J2EE enviroment where the pool and transaction lifecycles are controlled by a container (provided there is a way to get the current transactions's connection, something that can be done with Spring, not sure with standard J2EE).
Of course it would also be good for any app that has its own (eventually manual) transaction demarcation and connection pool handling
Issue Links
- depends upon
-
GEOT-2009
Fix transaction and connection handling in JDBCDataStore
-
I want to mention some facts.
1) 2 different scenarios
a) We have jdbc connections managed by a global JDBC transaction
(In an EJB container and, if supported, in a Servlet Container)
b) We have standalone jdbc connections managed by usercode, not participating in any global Transaction.
(in an EJB container , in a servlet container, in a java program,....)
For a) it is forbidden to use commit/rollback, for b) user code is responsible for commit/rollback
2) We can ignore the global transaction, it is of no interest for jdbc-ng. If jdbc-ng has an error condition, throw
a checked exception (I think we do this). Never throw an unchecked exception because when this exception crosses the container
boundary, a rollback of the global transaction is executed (Uaaaaaaaaahhhhhh).
Btw, leaving the container with a checked exception causes a commit on the global transaction. E. g. passing an SQLException
from the ejb container to the servlet engine does a commit on the global transaction. This is a common error by j2ee programmers,
they have to use EJBContext>>setTransactionRollbackOnly before leaving the EJB container.
3) Andrea, you wrote
"provided there is a way to get the current transactions's connection, something that can be done with Spring, not sure with standard J2EE".
No, there is no way to get the current transactions's connection (The global transaction may have many jdbc connections) .
Think the other way around, a connection has an associated jdbc transaction and may be enrolled in a global transaction ,
ok, but these transactions are not of interest for jdbc-ng.
4) A good EJB Design avoids having statefull EJBs. I should be possible to create a JDBCFeatureStore (Source) and reuse
it with different jdbc connections. I am not sure if we can handle this.