|
From: Mattias J <mj...@ex...> - 2005-07-06 09:09:40
|
At 2005-07-06 09:43, you wrote:
>Mathias.
>
>Good info. I'll have a look. This Jakarta Commons solution does not
>come up in google if you use JTA in your search terms.
>
>Ok.. I had a quick look. Since it is not JTA/JCA compatible it seems
>like a similar solution currently implemented in hermes. Then again,
>it would not be wrong to drop these 'home made' extensions in favour
>of existing ones right? (not that the home made solutions are bad,
>not at all. My own cake is always better than the cake from the mall ;-)
>
>Is your solution a kind of java connector?
Nope. I have very limited knowledge of JCA.
It is a simple class wrapping java.io.File and implementing
javax.transaction.xa.XAResource.
>Can it be used as a drop-inn in any j2ee container?
It assumes the transaction manager can be found in JNDI
"java:comp/TransactionManager". But of course that can be made configurable.
>If so, is it available to others ;-)
It is both closed source and specific to our environment. We use it
(mainly) when creating files. They are created as temporary files,
and when the JTA transaction commits, the file is moved to the final
destination and given the final name. If the transaction is rolled
back, the file is deleted.
Here is the outline of the implementation:
In constructor of factory:
// Enlist as resource in transaction
TransactionManager tm = (TransactionManager)new
InitialContext().lookup("java:comp/TransactionManager");
javax.transaction.Transaction tx = tm.getTransaction();
if(tx != null)
tx.enlistResource(this);
/** Manual delete */
public void delete() { // NOTE! Assumes newly created files, does
not work with existing files!
if(xid != null) { // If enlisted in transaction
// Delist from transaction
TransactionManager tm = (TransactionManager)new
InitialContext().lookup("java:comp/TransactionManager");
tm.getTransaction().delistResource(this, TMSUCCESS);
}
[[Perform delete]]
}
/**
* Close file and move to new directory. The method used by all
other close methods internally.
* @param newPath
* @param newName
*/
public final void rename(final String newName) {
if(xid == null) // If not part of a transaction
[[Perform rename]]
else
[[Remember name until commit]]
}
/////////////////////////////////////////////////////////////////////////////////////
// Methods to implement XAResource
/////////////////////////////////////////////////////////////////////////////////////
public int getTransactionTimeout() throws XAException {
return 0;
}
public boolean setTransactionTimeout(int i) throws XAException {
return false;
}
public boolean isSameRM(XAResource xaResource) throws XAException {
return xaResource == this; // If same file
}
public Xid[] recover(int flags) throws XAException {
return null;
}
/**
* Prepare for commit. After this we need to be sure the commit
will be successful. For
* example we need to make sure there is enought disc space for the file.
*/
public int prepare(Xid xid) throws XAException {
// We could do all the file flushing here
[[Assert file name is set]]
return XA_OK;
}
public void forget(Xid xid) throws XAException {
this.xid = null;
}
public void rollback(Xid xid) throws XAException {
this.xid = null;
[[Delete the file]]
}
public void end(Xid xid, int flags) throws XAException {
}
public void start(Xid xid, int flags) throws XAException {
this.xid = xid;
}
public void commit(Xid xid, boolean onePhase) throws XAException {
if([[File not yet manually deleted]]) { // Unless the file was
deleted (and delisted)
[[Perform rename/move]]
}
this.xid = null;
}
/ Mattias Jiderhamn
|