|
From: <jue...@we...> - 2003-03-20 09:44:11
|
I should note that I've reworked JndiServices a bit, else the contrast =
to JdbcTemplate is not obvious.
There was half-baked support for a pluggable ContextFactory in =
JndiServcies that de facto was not used. IMHO, a major advantage of JNDI =
is its universal lookup mechanism, just "new InitialContext()" and =
you're there. A pluggable ContextFactory makes this significantly =
harder, and I'm not sure about the benefits. Any JNDI implementation =
should be configurable so that "new InitialContext()" retrieves a =
correct context in any case.
Thus, I've removed ContextFactory support and reworked JndiServices into =
a static helper class, featuring the same methods as static versions. =
"DataSourceUtils.getDataSourceFromJndi" did not use JndiServices =
previously but does so now (and I've renamed it, it was =
"getDataSourceFromJNDI" before). BTW, I've added a new alternative =
constructor to JdbcTemplate, taking a data source name and resolving it =
via DataSourceUtils.
I haven't committed these changes yet, but I will soon if noone objects. =
This is completely independent of the JTA stuff, of course. Two more =
independent changes that I haven't checked in yet are the moved mock =
objects and the reworked MessageSourceResolvable stuff. I guess I will =
commit everything tomorrow, including my preliminary JTA support if Rod =
likes me to.
Juergen
-----Original Message-----
From: j=FCrgen h=F6ller [werk3AT]=20
Sent: Thursday, March 20, 2003 9:50 AM
To: spr...@li...
Subject: RE: [Springframework-developer] Update
Hi Rod,
Regarding AOP and transaction management: I'm really eager to look at =
that stuff. I'm currently trying to settle on a transaction handling way =
for our applications here at werk3AT, and this isn't as straightforward =
as it should be.
Interestingly, I've come up with something very similar to a thing your =
proposed: A com.interface21.jta package providing a JtaServices class =
and an associated TransactionCallback, among other things caring for the =
exception handling and transforming those awkward, loose JTA exceptions =
to the exception hierarchy in com.interface21.dao. We seem to duplicate =
effort here, so I guess we should try to synchronize. There's not much =
code involved, so I don't think that there has been much overhead yet.
Some sample application code using my current version:
public static void executeTransaction() {
JtaServices.execute(
new TransactionCallback() {
public void doInTransaction() {
executeTestUpdate();
executeTestQuery();
}
}
);
}
Obvious issues are:
- I use a JtaServices static helper class analogous to JndiServices =
rather than a JtaTemplate instance analogous to JdbcTemplate. The reason =
is that there's not much state involved currently: A thread only has one =
associated JTA UserTransaction, just like it only has one associated =
JNDI InitialContext - in constrast to potentially multiple JDBC =
DataSources. Does your implementation have more state that justifies =
using an instance, possibly configuration or potential subclassing?
- Instead of a new exception hierarchy in com.interface21.transaction, I =
chose to integrate the transaction exceptions into com.interface21.dao. =
The rationale behind this is that transactions are an inherent aspect of =
data access. Currently, I have only one new exception, namely =
DataAccessTransactionRollbackException. Other exceptions like JTA's =
SystemException get converted to the existing =
DataAccessResourceFailureException. The existing =
DeadlockLoserDataAccessException is now a subclass of =
DataAccessTransactionRollbackException.
- TransactionCallback.doInTransaction() does not throw any checked =
exceptions. Instead, any RuntimeException thrown causes the transaction =
to roll back (resp. a warning written to the log that the transaction =
should have been rolled back, when JTA isn't available), and gets =
rethrown to the caller. AOP allows for much more flexibility in this =
respect, but I don't see a more flexible way for the callback approach.
- A special characteristic of my version is that it allows for working =
without JTA as a fallback. If there's a problem retrieving the =
UserTransaction from JNDI and applying it, a warning gets written to the =
log, and the transactional application code gets executed without a =
transaction, using autocommit=3Dtrue. We currently use this for test =
suites that run in a plain VM with just a JNDI DataSource mock. It is =
also meant for being able to run your application in a non-JTA =
environment too (e.g. for a development or demo environment), while =
benefiting from JTA when available. BTW, an overloaded version of =
JtaServices.execute disables this fallback and enforces JTA =
availability.
- My current stuff may not be too sophisticated, but it works and I =
consider it beta quality. I have tested it with Tomcat 4.0/4.1 (both =
with and without Tyrex 0.9.7/1.0) and Resin 2.1, using Driver-backed =
"enabled" DataSources and real XADataSources. A version of Spring's JTA =
stuff can and should definitely make it for 0.9, as I consider =
transaction handling a very important issue.
- Note that at werk3AT, we don't need any distributed transactions yet: =
We simply use JTA for convenient transaction demarcation in high-level =
services. The underlying lower-level data access services use either =
JDBC via a JNDI datasource or the O/R mapping toolkit Hibernate (with a =
JNDI datasource underneath). This works nicely if the JNDI datasource is =
XA-capable, and allows for clear separation of concerns. Of course, =
one-phase commit is enough for this, so I don't mind "enabled" =
DataSources that are not truly XA-capable (like MySQL's). An obvious =
benefit of still basing our applications' transaction handling on JTA is =
that extending them to more datasources is very smooth.
- I've recently reviewed Hibernate's JTA usage in detail, i.e. in its =
source code. It's very straightforward, the only major issue is managing =
cache state. Hibernate needs to register a synchronization with the =
container's transaction manager, to be able to update the cache on =
transaction commit or rollback accordingly. Unfortunately, the JNDI =
location of the transaction manager is unspecified in J2EE, so Hibernate =
has a lookup interface and implementations for various application =
serves. In the current Hibernate version, this only works with explicit =
transaction handling in the data access code, and configuring Hibernate =
for JTA. Hibernate transactions then simply take part in existing JTA =
transactions, or start new ones if necessary. In the autocommit case, =
Hibernate cannot guarantee correct cache state, as there's no JTA =
synchronization then. This will be addressed by a JCA adapter in =
Hibernate 2.1.
- Finally, regarding PlatformTransactionManager: What functionality does =
this interface address in detail? Do we need to synchronize anything? =
Any concrete use cases?
So, how should we proceed? I could check in my current stuff, so that =
you can review it and merge it with your version. Of course, we can =
proceed the other way round too. What do you prefer?
Regards,
Juergen
P.S.:
Orion 2.0 has just been released. Hurray, it isn't dead! ;-) Seriously, =
I will definitely look at it soon. Hopefully, the web stuff is fully =
Servlet 2.3 compliant now.
|