User: sparre
Date: 01/04/29 01:12:52
Added: src/main/org/jboss/tm/usertx/server
ClientUserTransactionService.java
ClientUserTransactionServiceMBean.java
UserTransactionSessionFactoryImpl.java
UserTransactionSessionImpl.java
Log:
Added UserTransaction support for stand-alone clients.
Revision Changes Path
1.1
jboss/src/main/org/jboss/tm/usertx/server/ClientUserTransactionService.java
Index: ClientUserTransactionService.java
===================================================================
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.tm.usertx.server;
import java.rmi.server.UnicastRemoteObject;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.Reference;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.jboss.util.ServiceMBeanSupport;
import org.jboss.tm.usertx.client.ClientUserTransaction;
import org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory;
/**
* This is a JMX service handling the serverside of UserTransaction
* usage for standalone clients.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Ole Husgaard</a>
* @version $Revision: 1.1 $
*/
public class ClientUserTransactionService
extends ServiceMBeanSupport
implements ClientUserTransactionServiceMBean
{
// Constants -----------------------------------------------------
public static String JNDI_NAME = "UserTransaction";
public static String FACTORY_NAME = "UserTransactionSessionFactory";
// Attributes ----------------------------------------------------
MBeanServer server;
// Keep a reference to avoid DGC.
private UserTransactionSessionFactory factory;
// ServiceMBeanSupport overrides ---------------------------------
public String getName()
{
return "Client UserTransaction manager";
}
protected ObjectName getObjectName(MBeanServer server, ObjectName name)
throws javax.management.MalformedObjectNameException
{
this.server = server;
return new ObjectName(OBJECT_NAME);
}
protected void startService()
throws Exception
{
factory = new UserTransactionSessionFactoryImpl();
Context ctx = new InitialContext();
ctx.bind(FACTORY_NAME, factory);
ctx.bind(JNDI_NAME, ClientUserTransaction.getSingleton());
}
protected void stopService()
{
try {
Context ctx = new InitialContext();
ctx.unbind(FACTORY_NAME);
ctx.unbind(JNDI_NAME);
// Force unexport, and drop factory reference.
try {
UnicastRemoteObject.unexportObject(factory, true);
} catch (Exception ex) {
log.exception(ex);
}
factory = null;
} catch (Exception e) {
log.exception(e);
}
}
}
1.1
jboss/src/main/org/jboss/tm/usertx/server/ClientUserTransactionServiceMBean.java
Index: ClientUserTransactionServiceMBean.java
===================================================================
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.tm.usertx.server;
/**
* MBean for ClientUserTransaction service.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Ole Husgaard</a>
* @version $Revision: 1.1 $
*/
public interface ClientUserTransactionServiceMBean
extends org.jboss.util.ServiceMBean
{
public static final String OBJECT_NAME = ":service=ClientUserTransaction";
}
1.1
jboss/src/main/org/jboss/tm/usertx/server/UserTransactionSessionFactoryImpl.java
Index: UserTransactionSessionFactoryImpl.java
===================================================================
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.tm.usertx.server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import org.jboss.tm.usertx.interfaces.UserTransactionSession;
import org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory;
/**
* The RMI remote UserTransaction session factory implementation.
*/
public class UserTransactionSessionFactoryImpl
extends UnicastRemoteObject
implements UserTransactionSessionFactory
{
/**
* A no-args constructor that throws <code>RemoteException</code>.
*/
public UserTransactionSessionFactoryImpl()
throws RemoteException
{
super();
}
//
// implements interface UserTransactionSessionFactory
//
/**
* Create and return a new session.
*
* @return A new user transaction session.
*/
public UserTransactionSession newInstance()
throws RemoteException
{
return new UserTransactionSessionImpl();
}
}
1.1
jboss/src/main/org/jboss/tm/usertx/server/UserTransactionSessionImpl.java
Index: UserTransactionSessionImpl.java
===================================================================
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.tm.usertx.server;
import java.util.HashMap;
import java.util.Map;
import java.util.Collection;
import java.util.Iterator;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.Unreferenced;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.transaction.UserTransaction;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.Status;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import javax.transaction.RollbackException;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import org.jboss.tm.TransactionPropagationContextFactory;
import org.jboss.logging.Logger;
import org.jboss.tm.usertx.interfaces.UserTransactionSession;
/**
* The RMI remote UserTransaction session implementation.
* It handles transactions on behalf of a single client.
*/
public class UserTransactionSessionImpl
extends UnicastRemoteObject
implements UserTransactionSession, Unreferenced
{
/** Cache a reference to the TM. */
private static TransactionManager tm = null;
/**
* Get a reference to the transaction manager.
*/
protected static TransactionManager getTransactionManager()
{
if (tm == null) {
try {
Context ctx = new InitialContext();
tm = (TransactionManager)ctx.lookup("java:/TransactionManager");
} catch (NamingException ex) {
Logger.exception(ex);
}
}
return tm;
}
/** Cache a reference to the TPC Factory. */
private static TransactionPropagationContextFactory tpcFactory = null;
/**
* Get a reference to the TPC Factory
*/
protected static TransactionPropagationContextFactory getTPCFactory()
{
if (tpcFactory == null) {
try {
Context ctx = new InitialContext();
tpcFactory =
(TransactionPropagationContextFactory)ctx.lookup("java:/TransactionPropagationContextExporter");
} catch (NamingException ex) {
Logger.exception(ex);
}
}
return tpcFactory;
}
/**
* Maps the TPCs of all active transactions to their transactions.
*/
private Map activeTx = new HashMap();
/**
* A no-args constructor that throws <code>RemoteException</code>.
*/
public UserTransactionSessionImpl()
throws RemoteException
{
super();
}
//
// implements interface UserTransactionSession
//
/**
* Destroy this session.
*/
public void destroy()
throws RemoteException
{
unexportObject(this, true);
unreferenced();
}
/**
* Start a new transaction, and return its TPC.
*
* @param timeout The timeout value for the new transaction, in seconds.
*
* @return The transaction propagation context for the new transaction.
*/
public Object begin(int timeout)
throws RemoteException,
NotSupportedException,
SystemException
{
TransactionManager tm = getTransactionManager();
// Set timeout value
tm.setTransactionTimeout(timeout);
// Start tx, and get its TPC.
tm.begin();
Object tpc = getTPCFactory().getTransactionPropagationContext();
// Suspend thread association.
Transaction tx = tm.suspend();
// Remember that a new tx is now active.
activeTx.put(tpc, tx);
// return the TPC
return tpc;
}
/**
* Commit the transaction.
*
* @param tpc The transaction propagation context for the transaction.
*/
public void commit(Object tpc)
throws RemoteException,
RollbackException,
HeuristicMixedException,
HeuristicRollbackException,
SecurityException,
IllegalStateException,
SystemException
{
Transaction tx = (Transaction)activeTx.get(tpc);
if (tx == null)
throw new IllegalStateException("No transaction.");
tx.commit();
activeTx.remove(tpc);
}
/**
* Rollback the transaction.
*
* @param tpc The transaction propagation context for the transaction.
*/
public void rollback(Object tpc)
throws RemoteException,
SecurityException,
IllegalStateException,
SystemException
{
Transaction tx = (Transaction)activeTx.get(tpc);
if (tx == null)
throw new IllegalStateException("No transaction.");
tx.rollback();
activeTx.remove(tpc);
}
/**
* Mark the transaction for rollback only.
*
* @param tpc The transaction propagation context for the transaction.
*/
public void setRollbackOnly(Object tpc)
throws RemoteException,
IllegalStateException,
SystemException
{
Transaction tx = (Transaction)activeTx.get(tpc);
if (tx == null)
throw new IllegalStateException("No transaction.");
tx.setRollbackOnly();
}
/**
* Return status of the transaction.
*
* @param tpc The transaction propagation context for the transaction.
*/
public int getStatus(Object tpc)
throws RemoteException,
SystemException
{
Transaction tx = (Transaction)activeTx.get(tpc);
if (tx == null)
return Status.STATUS_NO_TRANSACTION;
return tx.getStatus();
}
//
// implements interface Unreferenced
//
/**
* When no longer referenced, be sure to rollback any
* transactions that are still active.
*/
public void unreferenced()
{
Logger.debug("Lost connection to UserTransaction client.");
if (!activeTx.isEmpty()) {
Logger.error("Lost connection to UserTransaction clients: " +
"Rolling back " + activeTx.size() +
" active transaction(s).");
Collection txs = activeTx.values();
Iterator iter = txs.iterator();
while (iter.hasNext()) {
Transaction tx = (Transaction)iter.next();
try {
tx.rollback();
} catch (Exception ex) {
Logger.exception(ex);
}
}
}
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development