Java Transaction API in a desktop applicationJTA in a desktop applicationDownload the source code here. Not so recently I was involved in a project divided in
So far, so good - but these parts should share exactly the same logic, almost the same database structure and we don't like to write anything twice! Of course the web portal would run in a fully J2EE application server and obviously the desktop application won't. So our strategy was:
The desktop application framework should handle connection polling, logs and - most important - transactions. Hence this sample. The sample applicationThis sample is provided AS IT IS under the Apache Software Foundation licence. It uses portions of Jonas application server code as a simple implementation of JTA. These portions of code are well named (see the tm package) When I developed this framework (almost a year from now) I din't know Apache DBCP, so here it is yet another Pooling framework :-\ But we can say that this pooling capability is transaction-aware as it enlists its resource if it detect a transaction in the current thread. We had a different classloader strategy, which I had stripped from this sample, so ignore classloader handling code. How to useWell, don't try to run the unit tests. Unfortunatelly they depends an environment we had at the project (three different databases: MSSQL, Oracle 8 and HSQLDB). The process can be defined this way:
The business classes code are completely unaware of transactions. That's very nice. All they have to do is use JNDI to obtain their resources and voila!
public void createNew() throws Exception
{
Apolice apol = (Apolice)
ClassFactory.createConcreteInstance(this.getClass().getClassLoader(),
"br.com.keldor.core.sample.business.Apolice");
apol.setupDatabaseTables();
}
And the implementation:
public class ApoliceImpl extends AbstractInspectable implements Apolice
{
static
{
// Thats pretty ugly !
Preferences pref = Preferences.userNodeForPackage(ApoliceImpl.class);
pref.put(
"Metadata",
"<?xml version=\"1.0\" standalone=\"yes\"?>" +
"<Metadata class=\"br.com.keldor.core.sample.business.ApoliceImpl\">" +
" <MethodInfo>" +
" <name>store</name>" +
" <Transaction>Required</Transaction>" +
" </MethodInfo>" +
" <MethodInfo>" +
" <name>load</name>" +
" <Transaction>Supports</Transaction>" +
" </MethodInfo>" +
" <MethodInfo>" +
" <name>remove</name>" +
" <Transaction>Never</Transaction>" +
" </MethodInfo>" +
" <MethodInfo>" +
" <name>setupDatabaseTables</name>" +
" <Transaction>Required</Transaction>" +
" </MethodInfo>" +
"</Metadata>");
}
....
/** Transaction Required */
public void setupDatabaseTables() throws Exception
{
ApoliceServices serv = new ApoliceServices();
serv.setupDatabase();
}
/** Transaction Required */
public void store() throws Exception
{
...
}
/** Transaction Supports */
public void load(int id) throws Exception
{
...
}
/** Transaction Never */
public void remove(int id) throws Exception
{
...
}
}
What to do from hereWell, a refactor will be nice :-) Today XML is used as metadata, but attributes will be better. Use Avalon Merlin or Fortress would be nice!!! If you use this and improve this framework, let me know, ok? |